为什么在Python中遍历字典时必须调用.items()?

134 投票
2 回答
83802 浏览
提问于 2025-04-16 04:19

为什么在字典中要调用 items() 才能遍历键值对?比如:

dic = {'one': '1', 'two': '2'}
for k, v in dic.items():
    print(k, v)

为什么遍历字典时,这不是默认的行为呢?

for k, v in dic:
    print(k, v)

2 个回答

10

我的猜测:使用完整的元组在循环时会更直观,但在用 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__)。但这种小小的不一致可能会让人感到困惑,而且有点不一致。

176

对于每一个Python容器C,我们期望

for item in C:
    assert item in C

这个代码能正常运行——如果在循环中使用的in和检查某个元素是否存在的in有完全不同的意思,你会不会觉得很惊讶呢?我肯定会!对于列表、集合、元组等,in的用法自然是这样的。

所以,当C是一个字典时,如果在for循环中使用in返回的是键/值对的元组,那么根据“最小惊讶原则”,在检查某个元素是否存在时,in也必须接受这样的元组作为左边的操作数。

这样做有多有用呢?其实没什么用,基本上让if (key, value) in Cif 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。)

撰写回答