[英]Iterating over dictionary items(), values(), keys() in Python 3
If I understand correctly, in Python 2, iter(d.keys())
was the same as d.iterkeys()
. 如果我理解正确,在Python 2中,
iter(d.keys())
与d.iterkeys()
相同。 But now, d.keys()
is a view, which is in between the list and the iterator. 但是现在,
d.keys()
是一个视图,它位于列表和迭代器之间。 What's the difference between a view and an iterator? 视图和迭代器之间有什么区别?
In other words, in Python 3, what's the difference between 换句话说,在Python 3中,有什么区别
for k in d.keys()
f(k)
and 和
for k in iter(d.keys())
f(k)
Also, how do these differences show up in a simple for
loop (if at all)? 另外,这些差异如何在一个简单的
for
循环中显示(如果有的话)?
I'm not sure if this is quite an answer to your questions but hopefully it explains a bit about the difference between Python 2 and 3 in this regard. 我不确定这是否是对你的问题的完全答案,但希望它能解释一下Python 2和3在这方面的区别。
In Python 2, iter(d.keys())
and d.iterkeys()
are not quite equivalent, although they will behave the same. 在Python 2中,
iter(d.keys())
和d.iterkeys()
并不完全等效,尽管它们的行为相同。 In the first, keys()
will return a copy of the dictionary's list of keys and iter
will then return an iterator object over this list, with the second a copy of the full list of keys is never built. 在第一个中,
keys()
将返回字典的键列表的副本,然后iter
将在此列表上返回一个迭代器对象,第二个将永远不会构建完整的键列表的副本。
The view objects returned by d.keys()
in Python 3 are iterable (ie an iterator can be made from them) so when you say for k in d.keys()
Python will create the iterator for you. 由Python 3中的
d.keys()
返回的视图对象是可迭代的 (即迭代器可以由它们构成)所以当你for k in d.keys()
说for k in d.keys()
Python会为你创建迭代器。 Therefore your two examples will behave the same. 因此,您的两个示例将表现相同。
The significance in the change of the return type for keys()
is that the Python 3 view object is dynamic. 更改
keys()
的返回类型的重要性在于Python 3视图对象是动态的。 ie if we say ks = d.keys()
and later add to d
then ks
will reflect this. 即如果我们说
ks = d.keys()
然后加到d
那么ks
将反映这一点。 In Python 2, keys()
returns a list of all the keys currently in the dict. 在Python 2中,
keys()
返回当前dict中所有键的列表。 Compare: 相比:
Python 3 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 Python 2.x
>>> d = { "first" : 1, "second" : 2 }
>>> ks = d.keys()
>>> ks
['second', 'first']
>>> d["third"] = 3
>>> ks
['second', 'first']
As Python 3's keys()
returns the dynamic object Python 3 doesn't have (and has no need for) a separate iterkeys
method. 由于Python 3的
keys()
返回动态对象,Python 3没有(并且不需要)单独的iterkeys
方法。
Further clarification 进一步澄清
In Python 3, keys()
returns a dict_keys
object but if we use it in a for
loop context for k in d.keys()
then an iterator is implicitly created. 在Python 3中,
keys()
返回一个dict_keys
对象,但如果我们for k in d.keys()
的for
循环上下文中使用它,则隐式创建迭代器。 So the difference between for k in d.keys()
and for k in iter(d.keys())
is one of implicit vs. explicit creation of the iterator. 因此
for k in d.keys()
for k in iter(d.keys())
之间的差异是迭代器的隐式与显式创建之一。
In terms of another difference, whilst they are both dynamic, remember if we create an explicit iterator then it can only be used once whereas the view can be reused as required. 就另一个区别而言,虽然它们都是动态的,但请记住,如果我们创建一个显式迭代器,那么它只能使用一次,而视图可以根据需要重用。 eg
例如
>>> 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
Also, notice that if we create an explicit iterator and then modify the dict then the iterator is invalidated: 另外,请注意,如果我们创建一个显式迭代器然后修改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
In Python 2, given the existing behaviour of keys
a separate method was needed to provide a way to iterate without copying the list of keys whilst still maintaining backwards compatibility. 在Python 2中,考虑到
keys
的现有行为,需要一种单独的方法来提供一种迭代方法,而无需复制键列表,同时仍保持向后兼容性。 Hence iterkeys()
因此
iterkeys()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.