本机Python函数从列表中删除NoneType元素?

sol*_*les 31 python list nonetype

我在Python中使用Beautiful Soup来从HTML文件中删除一些数据.在某些情况下,Beautiful Soup会返回包含两者stringNoneType对象的列表.我想过滤掉所有的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
Run Code Online (Sandbox Code Playgroud)

但是,如果它存在,我很乐意使用内置的Python函数.我总是希望在可能的情况下简化我的代码.Python有内置函数可以NoneType从列表中删除对象吗?

Abs*_*Abs 60

我认为最简洁的方法是:

#lis = some list with NoneType's
filter(None, lis)
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的,因为它也会删除`0`,`False`和`''`元素. (33认同)
  • 很公平.你可以使用`filter(lambda x:x!= None,lis)`. (21认同)
  • 这更迂腐地正确:`lambda x: x is not None` (3认同)

Cha*_*guy 23

你可以使用列表理解来做到这一点:

clean = [x for x in lis if x != None]
Run Code Online (Sandbox Code Playgroud)

正如您在注释中所指出的那样is not,即使它基本上编译为相同的字节码:

clean = [x for x in lis if x is not None]
Run Code Online (Sandbox Code Playgroud)

您也可以使用filter(注意:这也将过滤空字符串,如果您想要更多地控制过滤器可以传递函数而不是None):

clean = filter(None, lis)
Run Code Online (Sandbox Code Playgroud)

如果你想要更高效的循环,总会有itertools方法,但这些基本方法应该适用于大多数日常情况.

  • 根据PEP 8,在与单身人士进行比较时,应使用“不是”而不是“!=”。 (2认同)
  • @ThorstenKranz 如果第一个参数是 `None`,它会过滤掉所有类似 `False` 的条目(`None`、空字符串、零等)。 (2认同)

jet*_*guy 7

对于那些从谷歌来到这里的人——不要使用这个!

UPD 2021:
在编写此答案时,提议的实现在语言语义方面绝对有效,但显然是一个黑客攻击。从那时起事情发生了变化,从 Python 3.9 开始,NotImplemented明确不鼓励在布尔上下文中评估。这是 Python 文档的摘录:

不推荐在布尔上下文中评估 NotImplemented。虽然它当前评估为 true,但它会发出 DeprecationWarning。它会在 Python 的未来版本中引发 TypeError。

为了历史,我会保留这个答案,但请注意,即使到了这个时候,这也有点不合时宜。根据您的要求坚持建议的列表理解解决方案或filter+ lambda

原始答案:
截至 2019 年初,Python 没有用于过滤 None 值的内置函数,这避免了删除零、空字符串等常见的陷阱。

在 Python3 中,您可以使用 .__ne__dunder 方法(或“魔术方法”,如果您愿意的话)来实现它:

>>> list1 = [0, 'foo', '', 512, None, 0, 'bar']
>>> list(filter(None.__ne__, list1))
[0, 'foo', '', 512, 0, 'bar']
Run Code Online (Sandbox Code Playgroud)

这是它的工作原理:

  • None.__ne__(None) --> 错误

  • None.__ne__(anything) --> 未实现

NotImplemented有效的例外是True,例如:

>>> bool(None.__ne__('Something'))
True
Run Code Online (Sandbox Code Playgroud)

  • 在过滤器中使用 dunder 方法一点也不优雅。这是一个丑陋的黑客行为。在这种情况下,列表理解是首选。 (3认同)

Tho*_*anz 6

清单理解,作为其他建议的答案,或者出于完整性考虑:

clean = filter(lambda x: x is not None, lis)
Run Code Online (Sandbox Code Playgroud)

如果列表很大,则迭代器方法会更好:

from itertools import ifilter
clean = ifilter(lambda x: x is not None, lis)
Run Code Online (Sandbox Code Playgroud)

  • 给未来读者的一般注意事项:在 Python3 中,“filter”**已经**返回一个迭代器,因此第二种方法不是必需的。它仅与 Python 2 相关。如果您确实想要使用 Python 3 的列表,只需执行 `list(filter(...))` (2认同)