使用'for'循环遍历字典
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
print(key, 'corresponds to', d[key])
Python是怎么知道它只需要从字典中读取key
的呢?key
是一个特殊的关键词,还是仅仅是一个普通的变量呢?
17 个回答
遍历一个 dict
时,会按照没有特定顺序的方式遍历它的键,像这样:
(实际上,从 Python 3.6 开始,这种情况几乎不再存在,但要注意,只有从 Python 3.7 开始,这种行为才是被保证的。)
>>> d = {'x': 1, 'y': 2, 'z': 3}
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']
对于你的例子,使用 dict.items()
会更好:
>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]
这样你会得到一个元组的列表。当你像这样循环遍历它们时,每个元组会自动拆分成 k
和 v
:
for k,v in d.items():
print(k, 'corresponds to', v)
在遍历 dict
时使用 k
和 v
作为变量名是很常见的,尤其是当循环体只有几行代码时。如果循环比较复杂,使用更具描述性的名字可能会更好:
for letter, number in d.items():
print(letter, 'corresponds to', number)
养成使用格式化字符串的习惯是个好主意:
for letter, number in d.items():
print('{0} corresponds to {1}'.format(letter, number))
这里说的“key”并不是一个特殊的词,而是因为字典实现了一种叫做迭代器协议的东西。你也可以在自己的类里实现这个功能,比如可以参考这个问题,看看怎么构建类的迭代器。
对于字典来说,这个功能是在C语言层面实现的。具体的细节可以在PEP 234中找到。特别是里面有一部分叫“字典迭代器”:
字典实现了一个叫做tp_iter的槽,它返回一个高效的迭代器,可以遍历字典的键。[...] 这意味着我们可以写
for k in dict: ...
这个写法和下面的写法是等价的,但速度要快得多
for k in dict.keys(): ...
只要在循环中或者其他线程中不违反对字典的修改限制就可以。
字典还可以添加一些方法,返回不同类型的迭代器:
for key in dict.iterkeys(): ... for value in dict.itervalues(): ... for key, value in dict.iteritems(): ...
这意味着
for x in dict
其实是for x in dict.iterkeys()
的简写。
在Python 3中,dict.iterkeys()
、dict.itervalues()
和dict.iteritems()
这些方法已经不再支持了。可以用dict.keys()
、dict.values()
和dict.items()
来代替。
key
只是一个变量名。
for key in d:
这段代码会简单地遍历字典里的键,而不是键和值。如果你想同时遍历键和值,可以使用下面的代码:
对于 Python 3.x:
for key, value in d.items():
对于 Python 2.x:
for key, value in d.iteritems():
你可以自己试试,把 key
改成 poop
。
在 Python 3.x 中,iteritems()
被简单地替换成了 items()
,这个方法返回一个类似集合的视图,跟字典关联,就像 iteritems()
,但更好用。这个在 2.7 版本中也可以用,叫 viewitems()
。
操作 items()
在 Python 2 和 3 中都能用,但在 2 中它会返回字典的 (key, value)
对的列表,这个列表不会反映在调用 items()
之后字典的任何变化。如果你想在 3.x 中得到 2.x 的效果,可以使用 list(d.items())
。