Ответ 1
Я думаю, что самый чистый способ сделать это:
#lis = some list with NoneType's
filter(None, lis)
Я использую Beautiful Soup в Python для очистки некоторых данных из файлов HTML. В некоторых случаях Beautiful Soup возвращает списки, содержащие объекты string
и NoneType
. Я хотел бы отфильтровать все объекты NoneType
.
В Python списки с содержащими NoneType
объектами не являются итерабельными, поэтому понимание списка не является для этого вариантом. В частности, если у меня есть список lis
, содержащий NoneTypes
, и я пытаюсь сделать что-то вроде [x for x in lis (some condition/function)]
, Python выдает ошибку TypeError: argument of type 'NoneType' is not iterable
.
Как мы видели в других сообщениях, просто реализовать эту функциональность в пользовательской функции. Вот мой вкус:
def filterNoneType(lis):
lis2 = []
for l in links: #filter out NoneType
if type(l) == str:
lis2.append(l)
return lis2
Однако, я бы хотел использовать встроенную функцию Python для этого, если он существует. Мне всегда нравится упрощать свой код, когда это возможно. У Python есть встроенная функция, которая может удалять объекты NoneType
из списков?
Я думаю, что самый чистый способ сделать это:
#lis = some list with NoneType's
filter(None, lis)
Вы можете сделать это, используя понимание списка:
clean = [x for x in lis if x != None]
Как указано в комментариях, вы также можете использовать is not
, даже если он по существу компилируется в тот же байт-код:
clean = [x for x in lis if x is not None]
Вы также можете использовать filter
(обратите внимание: это также будет фильтровать пустые строки, если вы хотите больше контролировать то, что вы фильтруете, вы можете передать функцию вместо None
):
clean = filter(None, lis)
Всегда существует подход itertools, если вы хотите более эффективный цикл, но эти основные подходы должны работать в повседневной жизни.
Пояснение списка, как и другие предложенные ответы или, для полноты:
clean = filter(lambda x: x is not None, lis)
Если список огромен, подход итератора превосходит:
from itertools import ifilter
clean = ifilter(lambda x: x is not None, lis)
Вы можете легко удалить все объекты NoneType
из списка, используя понимание списка:
lis = [i for i in lis if i is not None]
В Python3 вы можете реализовать это, используя метод .__ne__
dunder (или "волшебный метод", если хотите):
>>> list1 = [0, 'foo', '', 512, None, 0, 'bar']
>>> list(filter(None.__ne__, list1))
[0, 'foo', '', 512, 0, 'bar']
Вот как это работает:
None.__ne__(None)
→ Неверно
None.__ne__(
что угодно )
→ Не реализовано
NotImplemented
эффективно True
, например:
>>> bool(None.__ne__('Something'))
True
По состоянию на начало 2019 года в Python не было встроенной функции для фильтрации значений None, что позволяет избежать распространенных ошибок при удалении нулей, пустых строк и т.д.