为什么必须调用 items()来迭代字典中的键值对。
items()
dic = {'one': '1', 'two': '2'} for k, v in dic.items(): print(k, v)
为什么这不是在字典上迭代的默认行为呢
for k, v in dic: print(k, v)
我的猜测是: 使用完整的 tuple 对于循环来说更加直观,但是对于使用 in测试成员资格来说可能就不那么直观了。
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__)。但是,这种小小的不一致会让人有些困惑,并且,嗯,不一致。
for ... in
__contains__
__iter__
对于每个 python 容器 C,期望是
for item in C: assert item in C
如果 in(循环子句)的一个意思与另一个(存在检查)的意思完全不同,你不会感到惊讶吗?我当然愿意!对于列表、集合、元组,它自然是这样工作的... ..。
因此,当 C是一个字典时,如果 in要在 for循环中产生键/值元组,那么根据最小惊讶原则,in也必须在遏制检查中将这样一个元组作为其左边的操作数。
C
for
那会有多大用处?实际上非常无用,基本上使 if (key, value) in C成为 if C.get(key) == value的同义词——这是一个检查,我相信我可能已经执行过,或者想要执行的,比 if k in C实际执行的 手段少100倍,检查键 只有的存在并完全忽略值。
if (key, value) in C
if C.get(key) == value
if k in C
另一方面,只想在键上循环是很常见的,例如:
for k in thedict: thedict[k] += 1
同时拥有价值并不会特别有帮助:
for k, v in thedict.items(): thedict[k] = v + 1
实际上有些不那么清晰,不那么简洁。(请注意,items是获取键/值对的“正确”方法的原拼法,不幸的是,那时这种访问器返回整个列表,所以为了支持“只是迭代”,必须引入另一种拼写方法,而 iteritems就是这样——在 Python 3中,与以前的 Python 版本向后兼容性约束大大削弱,它又变成了 items)。
items
iteritems