运行以下脚本时
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
我希望输出为空(第一个dict不匹配,第二个缺少键'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
错误?
我确信这是一个明显的错误,但是我看代码越多,我看到的机会就越少:)
答案 0 :(得分:4)
你确实在迭代,因为这就是运算符in
的工作方式。执行:if 'Bond' not in d.get('b'):
Python将在左操作数('Bond'
)内查找d.get('b')
。第二个条目中的d.get('b') == None
因此是例外。
您可以将第二个参数传递给get
,这个参数将被解释为默认值,以便在找不到要缓解此if
子句的元素时获取:
if 'Bond' not in d.get('b',[]):
答案 1 :(得分:2)
使用d.get('b', '')
代替d.get('b')
。
默认情况下dict.get
如果您提供的密钥不存在,则返回None
,这不是可迭代的或有任何方法可以调用。因此,只需将额外参数传递给get
即可避免默认返回值None
。请参阅docstring:
D.get(k [,d]) - &gt;如果k在D中则为D [k],否则为d。 d默认为无。
答案 2 :(得分:2)
在第二次迭代中,d
将为{'a': 'bonjour monde'}
,其中没有密钥b
。
d.get('b')
将返回None
,如果找不到密钥,dict.get
将返回None
。并且in
运算符将RHS视为可迭代的。这就是你得到这个错误的原因。
你可以简单地避免这样做,就像这样
for d in dictlist:
if 'b' in d and 'Bond' not in d['b']: