2014-03-04 101 views
1

當運行下面的腳本爲什麼「NoneType」不可迭代「錯誤,當我不迭代?

dictlist = [ 
    {'a': 'hello world', 'b': 'my name is Bond'}, 
    {'a': 'bonjour monde'} 
] 

for d in dictlist: 
    if 'Bond' not in d.get('b'): 
     print d 

我預期的輸出是空的(第一字典確實不匹配,第二個是缺少關鍵'b'),但我得到的錯誤:

Traceback (most recent call last): 
    File "C:/dev/mytest.py", line 7, in <module> 
    if 'Bond' not in d.get('b'): 
TypeError: argument of type 'NoneType' is not iterable 

我很困惑:爲什麼有一個argument of type 'NoneType' is not iterable錯誤,而我不迭代(至少在該行)?

我相信這是一個明顯的錯誤,但我越是看代碼的機會少,我看到它:)

回答

2

在第二次迭代,d{'a': 'bonjour monde'},不具有關鍵bd.get('b')將返回None,因爲dict.get將返回None如果找不到密鑰。並且in運算符將RHS視爲可迭代的。這就是你得到這個錯誤的原因。

你可以簡單地避免這種情況,像這樣的

for d in dictlist: 
    if 'b' in d and 'Bond' not in d['b']: 
+0

謝謝。所有響應都很好 - 感謝額外的位(默認值不會有幫助,因爲它會匹配'if') – WoJ

+0

@WoJ不,只有默認值不匹配。請讓我知道,如果你有不同的理解。 – thefourtheye

+0

如果我在d.get('b',「」)中不使用'if'Bond',那麼當'b'不存在時,將返回一個空字符串,它將匹配'if'Bond'不在' - 這不是我想要的(''b''根本不存在,所以測試(從邏輯角度來看)是無效的)。 **你的代碼是好的**:i)''b''必須存在以便ii)它被檢查爲'Bond' – WoJ

4

你確實是迭代因爲這是運營商的方式in作品。當你這樣做時:if 'Bond' not in d.get('b'): Python會在左操作數(d.get('b'))內尋找'Bond'。第二項中的d.get('b') == None因此是例外。

你可以傳遞第二個參數給get這將被解讀爲默認值中沒有找到緩解這種if子句中的元素的情況下獲得:

if 'Bond' not in d.get('b',[]): 
2

使用d.get('b', ''),而不是d.get('b')

默認情況下dict.get返回None如果您提供的密鑰不存在,這不是一個可迭代的或有任何方法調用。所以只需傳遞一個額外的參數到get以避免默認返回值None。查看文檔字符串:

D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.

相關問題