If I understand correctly, in Python 2, iter(d.keys())
was the same as d.iterkeys()
. But now, d.keys()
is a view, which is in between the list and the iterator. What's the difference between a view and an iterator?
如果我理解正确的话,在Python 2中,iter(d.keys())与d.iterkeys()相同。但是现在,d.keys()是一个视图,位于列表和迭代器之间。视图和迭代器之间的区别是什么?
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循环中显示(如果有的话)?
1 个解决方案
#1
56
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. 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.
在Python 2中,iter(d.keys())和d.iterkeys()不是完全等价的,尽管它们的行为是相同的。首先,keys()将返回字典的密钥列表的副本,iter将在此列表中返回一个迭代器对象,第二个键的完整列表的副本永远不会被构建。
The view objects returned by d.keys()
in Python 3 are iterable (i.e. an iterator can be made from them) so when you say for k in d.keys()
Python will create the iterator for you. Therefore your two examples will behave the same.
Python 3中d.keys()返回的视图对象是可迭代的(例如,可以从它们中创建一个迭代器),所以当您在d.keys() Python中输入k时,Python将为您创建迭代器。因此你的两个例子的行为是一样的。
The significance in the change of the return type for keys()
is that the Python 3 view object is dynamic. i.e. if we say ks = d.keys()
and later add to d
then ks
will reflect this. In Python 2, keys()
returns a list of all the keys currently in the dict. Compare:
keys()返回类型更改的意义在于,Python 3视图对象是动态的。也就是说,如果我们说k = d。keys()然后把它加到d中,那么k就会反映出来。在Python 2中,keys()返回当前命令中所有键的列表。
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的键()返回动态对象,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. 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.
在Python 3中,keys()返回一个dict_keys对象,但是如果我们在d.keys()中为k在for循环上下文中使用它,那么将隐式地创建一个迭代器。所以k in d.keys()和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. e.g.
另一个区别是,虽然它们都是动态的,但请记住,如果我们创建一个显式迭代器,那么它只能使用一次,而视图可以根据需要重用。如。
>>> 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. Hence iterkeys()
在Python 2中,给定键的现有行为,需要一个单独的方法来提供一种不复制键列表的迭代方法,同时仍然保持向后兼容性。因此iterkeys()
#1
56
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. 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.
在Python 2中,iter(d.keys())和d.iterkeys()不是完全等价的,尽管它们的行为是相同的。首先,keys()将返回字典的密钥列表的副本,iter将在此列表中返回一个迭代器对象,第二个键的完整列表的副本永远不会被构建。
The view objects returned by d.keys()
in Python 3 are iterable (i.e. an iterator can be made from them) so when you say for k in d.keys()
Python will create the iterator for you. Therefore your two examples will behave the same.
Python 3中d.keys()返回的视图对象是可迭代的(例如,可以从它们中创建一个迭代器),所以当您在d.keys() Python中输入k时,Python将为您创建迭代器。因此你的两个例子的行为是一样的。
The significance in the change of the return type for keys()
is that the Python 3 view object is dynamic. i.e. if we say ks = d.keys()
and later add to d
then ks
will reflect this. In Python 2, keys()
returns a list of all the keys currently in the dict. Compare:
keys()返回类型更改的意义在于,Python 3视图对象是动态的。也就是说,如果我们说k = d。keys()然后把它加到d中,那么k就会反映出来。在Python 2中,keys()返回当前命令中所有键的列表。
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的键()返回动态对象,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. 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.
在Python 3中,keys()返回一个dict_keys对象,但是如果我们在d.keys()中为k在for循环上下文中使用它,那么将隐式地创建一个迭代器。所以k in d.keys()和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. e.g.
另一个区别是,虽然它们都是动态的,但请记住,如果我们创建一个显式迭代器,那么它只能使用一次,而视图可以根据需要重用。如。
>>> 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. Hence iterkeys()
在Python 2中,给定键的现有行为,需要一个单独的方法来提供一种不复制键列表的迭代方法,同时仍然保持向后兼容性。因此iterkeys()