为什么在Python中遍历字典时必须调用.items()?
为什么在字典中要调用 items()
才能遍历键值对?比如:
dic = {'one': '1', 'two': '2'}
for k, v in dic.items():
print(k, v)
为什么遍历字典时,这不是默认的行为呢?
for k, v in dic:
print(k, v)
2 个回答
我的猜测:使用完整的元组在循环时会更直观,但在用 in
检查成员资格时可能就不那么直观了。
if key in counts:
counts[key] += 1
else:
counts[key] = 1
如果你需要同时指定键和值来使用 in
,那段代码就不太好用了。我很难想象有什么场景需要同时检查字典中的键和值。通常只检查键会更自然。
# When would you ever write a condition like this?
if (key, value) in dict:
现在,in
操作符和 for ... in
不一定要操作同样的项目。从实现的角度来看,它们是不同的操作(__contains__
和 __iter__
)。但这种小小的不一致可能会让人感到困惑,而且有点不一致。
对于每一个Python容器C,我们期望
for item in C:
assert item in C
这个代码能正常运行——如果在循环中使用的in
和检查某个元素是否存在的in
有完全不同的意思,你会不会觉得很惊讶呢?我肯定会!对于列表、集合、元组等,in
的用法自然是这样的。
所以,当C
是一个字典时,如果在for
循环中使用in
返回的是键/值对的元组,那么根据“最小惊讶原则”,在检查某个元素是否存在时,in
也必须接受这样的元组作为左边的操作数。
这样做有多有用呢?其实没什么用,基本上让if (key, value) in C
和if C.get(key) == value
变成同义词——而我觉得我可能比起if k in C
这种检查,想要做这个检查的次数少了100倍,因为后者只检查键是否存在,完全不管值是什么。
另一方面,单独循环键是很常见的,比如:
for k in thedict:
thedict[k] += 1
有值也没什么特别的帮助:
for k, v in thedict.items():
thedict[k] = v + 1
其实这样反而不太清晰,也不够简洁。(注意,items
是获取键/值对的“正确”方法的原始拼写:不幸的是,那时候这样的访问方式返回的是整个列表,所以为了支持“仅仅迭代”,不得不引入另一种拼写,结果就是iteritems
——在Python 3中,由于与之前版本的兼容性限制大大减弱,它又变回了items
。)