1) Почти английский стиль:
Проверьте наличие, используя inоператор, затем примените removeметод.
if thing in some_list: some_list.remove(thing)
removeМетод будет удалить только первое вхождение thing, чтобы удалить все вхождения , которые можно использовать whileвместо if.
while thing in some_list: some_list.remove(thing)
- Достаточно просто, наверное, мой выбор. Для небольших списков (не выдерживает однострочников)
Такое отношение «стреляй первым - задавай вопросы - последнее» распространено в Python. Вместо того, чтобы заранее проверять, подходит ли объект, просто выполните операцию и поймайте соответствующие исключения:
try:
some_list.remove(thing)
except ValueError:
pass # or scream: thing not in some_list!
except AttributeError:
call_security("some_list not quacking like a list!")
Конечно, второе, за исключением пункта в вышеприведенном примере, имеет не только сомнительный юмор, но и совершенно ненужное (цель состояла в том, чтобы проиллюстрировать типизацию утки для людей, не знакомых с концепцией).
Если вы ожидаете многократного появления вещи:
while True:
try:
some_list.remove(thing)
except ValueError:
break
- немного многословно для этого конкретного случая использования, но очень идиоматично в Python.
- это работает лучше, чем # 1
- PEP 463 предложил более короткий синтаксис для try / кроме простого использования, который был бы здесь полезен, но не был одобрен.
Однако с помощью contextmanb contextlib's suppress () (представлен в python 3.4) приведенный выше код можно упростить до следующего:
with suppress(ValueError, AttributeError):
some_list.remove(thing)
Опять же, если вы ожидаете многократного появления вещи:
with suppress(ValueError):
while True:
some_list.remove(thing)
3) Функциональный стиль:
Около 1993, Python есть lambda, reduce(), filter()и map(), любезно Лисп хакера , который пропустил их и представили рабочие патчи *. Вы можете использовать filterдля удаления элементов из списка:
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
Существует ярлык, который может быть полезен для вашего случая: если вы хотите отфильтровать пустые элементы (фактически элементы, где bool(item) == False, например None, ноль, пустые строки или другие пустые коллекции), вы можете передать None в качестве первого аргумента:
cleaned_list = filter(None, some_list)
- [обновление] : в Python 2.x
filter(function, iterable)раньше было эквивалентно [item for item in iterable if function(item)](или [item for item in iterable if item]если первый аргумент None); в Python 3.x он теперь эквивалентен (item for item in iterable if function(item)). Тонкое отличие состоит в том, что фильтр, используемый для возврата списка, теперь работает как выражение генератора - это нормально, если вы перебираете только очищенный список и отбрасываете его, но если вам действительно нужен список, вы должны заключить filter()вызов с list()конструктором.
- * Эти ароматизированные конструкции Lispy считаются немного чужими в Python. Примерно в 2005 году Гвидо даже говорил об отбрасывании
filter - вместе со своими компаньонами mapи reduce(они еще не ушли, но reduceбыли перенесены в модуль functools , который стоит посмотреть, если вам нравятся функции высокого порядка ).
4) Математический стиль:
Список постижения стали предпочтительным стилем для списка манипуляций в Python , так как введенные в версии 2.0 по PEP 202 . Обоснованием этого является , что описания списки обеспечивают более краткий способ создания списков в ситуациях , где map()и filter()будет в настоящее время используются и / или вложенные циклы.
cleaned_list = [ x for x in some_list if x is not thing ]
Выражения генератора были введены в версии 2.4 PEP 289 . Выражение генератора лучше для ситуаций, когда вам не нужно (или вы не хотите) иметь полный список, созданный в памяти - например, когда вы просто хотите перебирать элементы по одному. Если вы перебираете список, вы можете думать о выражении-генераторе как о ленивом вычислении списка:
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
Ноты
- Вы можете использовать оператор неравенства
!=вместо is not( разница важна )
- для критиков методов, подразумевающих копию списка: вопреки распространенному мнению, выражения-генераторы не всегда более эффективны, чем списки - пожалуйста, запишите профиль, прежде чем жаловаться