2013-01-09 43 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)