2013-01-09 123 views
15

我在Python中使用Beautiful Soup来从HTML文件中刮取一些数据。在某些情况下,Beautiful Soup会返回包含stringNoneType对象的列表。我想过滤掉所有NoneType对象。本机Python函数从列表中删除NoneType元素?

在Python中,含有NoneType对象的列表是不可迭代的,因此列表理解不适用于此。具体而言,如果我有一个包含NoneTypes的列表lis,并且我尝试执行诸如[x for x in lis (some condition/function)]之类的操作,Python会抛出错误TypeError: argument of type 'NoneType' is not iterable

正如我们在other posts中看到的,在用户定义的函数中实现此功能很简单。这是我的味道:

def filterNoneType(lis): 
    lis2 = [] 
    for l in links: #filter out NoneType 
     if type(l) == str: 
      lis2.append(l) 
    return lis2 

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

+0

你错了,包含'None'的列表是不可迭代的。你可能(意外地)试图遍历'None'本身:'[x for None in]'。 –

回答

39

我认为最干净的方法是:

#lis = some list with NoneType's 
filter(None, lis) 
+21

这是错误的,因为它也会删除'0','False'和''''元素。 – thomaspaulb

+12

够公平的。你可以使用'filter(lambda x:x!= None,lis)'。 – Abs

18

为此,您可以使用列表理解:

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方法,但这些基本方法应该适用于大多数日常情况。

+1

根据PEP 8,与单身人士比较时,您应该使用'不是'而不是'!='。 – Tim

+0

filter()函数作为第一个参数 –

+1

@ThorstenKranz如果第一个参数是None,它将过滤掉所有False类条目('None',空字符串,零等)。 – bereal

1

你可以很容易地从列表中使用列表理解删除所有NoneType对象:

lis = [i for i in lis if i is not None] 
4

列表理解,或如建议其他的答案,为了完整起见:

clean = filter(lambda x: x is not None, lis) 

如果列表是巨大的,迭代器的方法是优越的:

from itertools import ifilter 
clean = ifilter(lambda x: x is not None, lis)