为什么必须调用iteritems()
来迭代字典中的键值对?即
dic = {'one':'1', 'two':'2'}
for k, v in dic.iteritems():
print k, v
为什么不是迭代字典的默认行为
for k, v in dic:
print k, v
答案 0 :(得分:170)
对于每个python容器C,期望是
for item in C:
assert item in C
如果in
(循环子句)的意义与另一种意义完全不同(存在检查),那么将会很好地传递 - 不会你发现它是惊人的?我肯定会的!它自然适用于列表,集合,元组......
因此,当C
是字典时,如果in
在for
循环中产生键/值元组,那么,根据最不惊讶的原则,{{1}还必须在收容检查中将这样的元组作为其左手操作数。
那会有用吗?确实很无用,基本上使in
成为if (key, value) in C
的同义词 - 这是我相信我可能已执行或想要执行的检查,比if C.get(key) == value
实际< em>表示,检查是否存在键并完全忽略该值。
另一方面,想要仅仅在键上循环是很常见的,例如:
if k in C
具有该值也无济于事:
for k in thedict:
thedict[k] += 1
实际上有点不那么清晰,不那么简洁。 (请注意,for k, v in thedict.items():
thedict[k] = v + 1
是用于获取键/值对的“正确”方法的原始拼写:遗憾的是,这些访问者返回整个列表的时候,所以支持“只是迭代”替代必须引入拼写,并且items
它是 - 在Python 3中,以前的Python版本的向后兼容性约束被大大削弱,它再次成为iteritems
。
答案 1 :(得分:9)
我的猜测:使用完整的元组对循环更直观,但使用in
测试成员资格可能更少。
if key in counts:
counts[key] += 1
else:
counts[key] = 1
如果必须同时指定in
的键和值,那么该代码将无法正常工作。我很难想象用例,你要检查关键的AND值是否都在字典中。仅测试键是更自然的。
# When would you ever write a condition like this?
if (key, value) in dict:
现在in
运算符和for ... in
不必运行相同的项目。在实施方面,它们是不同的操作(__contains__
与__iter__
)。但是这种微小的不一致会让人感到困惑,而且不一致。