python - 在 Python 3 中迭代字典 items()、values()、keys()

标签 python python-3.x dictionary iterator

如果我理解正确,在 Python 2 中,iter(d.keys())d.iterkeys() 相同。但是现在,d.keys() 是一个 View ,它位于列表和迭代器之间。 View 和迭代器有什么区别?

也就是说,在 Python 3 中,有什么区别

for k in d.keys()
    f(k)

for k in iter(d.keys())
    f(k)

此外,这些差异如何在一个简单的 for 循环中显示出来(如果有的话)?

最佳答案

我不确定这是否能很好地回答您的问题,但希望它能解释一下 Python 2 和 3 在这方面的区别。

在 Python 2 中,iter(d.keys())d.iterkeys() 并不完全等效,尽管它们的行为相同。在第一个中,keys() 将返回字典的键列表的副本,然后 iter 将在此列表上返回一个迭代器对象,第二个是永远不会构建完整的键列表。

d.keys() 在 Python 3 中返回的 View 对象是 iterable (即可以从它们中生成迭代器)所以当你说 for k in d.keys() Python 将为您创建迭代器。因此,您的两个示例的行为将相同。

keys()的返回类型变化的意义在于Python 3的 View 对象是动态的。也就是说,如果我们说 ks = d.keys() 然后添加到 d 那么 ks 将反射(reflect)这一点。在 Python 2 中,keys() 返回字典中当前所有键的列表。比较:

Python 3

>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
dict_keys(['second', 'first'])
>>> d["third"] = 3
>>> ks
dict_keys(['second', 'third', 'first'])

Python 2.x

>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
['second', 'first']
>>> d["third"] = 3
>>> ks
['second', 'first']

由于 Python 3 的 keys() 返回动态对象,Python 3 没有(也不需要)单独的 iterkeys 方法。

进一步说明

在 Python 3 中,keys() 返回一个 dict_keys 对象,但如果我们在 for 循环上下文中使用它 for k在 d.keys() 然后隐式创建一个迭代器。因此 for k in d.keys()for k in iter(d.keys()) 之间的区别是迭代器的隐式与显式创建之一。

另一个区别是,虽然它们都是动态的,但请记住,如果我们创建一个显式迭代器,那么它只能使用一次,而 View 可以根据需要重复使用。例如

>>> ks = d.keys()
>>> 'first' in ks
True
>>> 'second' in ks
True
>>> i = iter(d.keys())
>>> 'first' in i
True
>>> 'second' in i
False             # because we've already reached the end of the iterator

另外,请注意,如果我们创建一个显式迭代器,然后修改 dict,那么迭代器就会失效:

>>> i2 = iter(d.keys())
>>> d['fourth'] = 4
>>> for k in i2: print(k)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

在 Python 2 中,鉴于 keys 的现有行为,需要一个单独的方法来提供一种在不复制键列表的情况下进行迭代的方法,同时仍保持向后兼容性。因此 iterkeys()

关于python - 在 Python 3 中迭代字典 items()、values()、keys(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3616721/

相关文章:

python - Matplotlib:重新排序子图

python - dataframe.hist() 具有不同的 bin 大小

python - 我请求的页面不代表与BeautifulSoup4相同的结构

python - 列中的连接值取决于特定条件

python:遍历具有列表值的字典

python - 在 Python 中将来自两个不同字典的值相乘

python - 如何用另一个的 MultiIndex 对一个 MultiIndex DataFrame 进行切片

python - 用于 SWIG、Python 的 C 函数错误代码的 %typemap 和 %exception

python - 正向回顾没有达到我的预期

excel - 如何访问嵌套字典的键?