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
( разница важна )
- для критиков методов, подразумевающих копию списка: вопреки распространенному мнению, выражения-генераторы не всегда более эффективны, чем списки - пожалуйста, запишите профиль, прежде чем жаловаться
Обратите внимание, что это удалит только один экземпляр пустой строки из вашего списка (как и ваш код тоже). Может ли ваш список содержать более одного?
источник
Если
index
не найдена искомая строка, она выдает то,ValueError
что вы видите. Либо перехватите ValueError:или используйте
find
, который возвращает -1 в этом случае.источник
>>> s [u'Hello', u'Cool', u'Glam'] >>> i = s.find("") Traceback (most recent call last): File "<pyshell#42>", line 1, in <module> i = s.find("") AttributeError: 'list' object has no attribute 'find'
remove()
гораздо более прямолинеен: он непосредственно показывает, для чего предназначен код (в действительности нет необходимости в промежуточном индексеi
).Для полноты добавим этот ответ, хотя его можно использовать только при определенных условиях.
Если у вас очень большие списки, удаление из конца списка избавляет от необходимости использовать внутренние компоненты CPython
memmove
для ситуаций, когда вы можете переупорядочить список. Это дает прирост производительности для удаления из конца списка, так как он не понадобитсяmemmove
каждому элементу после того, как вы удаляете, - назад на один шаг (1) .Для разовых удалений разница в производительности может быть приемлемой, но если у вас большой список и вам нужно удалить много элементов - вы, вероятно, заметите снижение производительности.
Хотя, по общему признанию, в этих случаях поиск по полному списку, вероятно, также будет узким местом для производительности, если только элементы не находятся в начале списка.
Этот метод можно использовать для более эффективного удаления,
если допустимо изменение порядка в списке. (2)
Вы можете избежать появления ошибки, когда ее
item
нет в списке.set
, особенно если список не предназначен для хранения дубликатов.Однако на практике вам может потребоваться хранить изменяемые данные, которые нельзя добавить в
set
. Также проверьте на btree's, можно ли заказать данные.источник
И не делай ничего сложного:)
Просто
filter()
ваши теги.bool()
возвращаетFalse
пустые строки, поэтому вместоты должен написать
или, что еще лучше, поместите эту логику внутрь,
striplist()
чтобы она не возвращала пустые строки.источник
striplist
функция, как мне включить ваше решение: def striplist (l): "" "удаляет пробелы из строк в списке l" "" return ([x.strip () для x в l])[x.strip() for x in l if x.strip()]
или использовать Python встроенныйmap
иfilter
функции , как это:filter(bool, map(str.strip, l))
. Если вы хотите , чтобы проверить его, оценить это в интерактивном переводчика:filter(bool, map(str.strip, [' a', 'b ', ' c ', '', ' ']))
.None
вместоbool
первого аргумента аргумент.Вот еще один однострочный подход:
Он не создает копию списка, не делает несколько проходов по списку, не требует дополнительной обработки исключений и возвращает сопоставленный объект или None, если совпадения нет. Единственная проблема заключается в том, что это делает для длинного заявления.
В общем, при поиске однострочного решения, которое не вызывает исключений, next () - это путь, поскольку это одна из немногих функций Python, которая поддерживает аргумент по умолчанию.
источник
Все, что вам нужно сделать, это
но у этого метода есть проблема. Вы должны положить что-то в исключительное место, чтобы я нашел это:
источник