为什么在不迭代时会出现“'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
的错误,明明我并没有在那一行进行迭代呢?
我知道这肯定是个明显的错误,但越看代码,我越看不出问题出在哪里 :)
3 个回答
2
用 d.get('b', '')
替代 d.get('b')
。
默认情况下,dict.get
方法在你提供的键不存在时,会返回 None
,而 None
不是一个可以遍历的东西,也没有任何方法可以调用。所以,只需给 get
方法多传一个参数,就可以避免返回默认的 None
。看看文档里的说明:
D.get(k[,d]) -> 如果 k 在 D 中,返回 D[k],否则返回 d。d 默认是 None。
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
的值会变成 {'a': 'bonjour monde'}
,这个字典里没有键 b
。所以当你用 d.get('b')
去查找时,它会返回 None
,因为 dict.get
方法在找不到指定的键时会返回 None
。而 in
操作符会把右边的内容当作一个可迭代的对象来处理。这就是你会遇到这个错误的原因。
你可以简单地这样避免这个问题:
for d in dictlist:
if 'b' in d and 'Bond' not in d['b']: