什么时候应使用iteritems()代替items()?

问题:什么时候应使用iteritems()代替items()?

items()代替iteritems()在所有地方使用是否合法?为什么iteritems()从Python 3 中删除?似乎是一种了不起的,有用的方法。它背后的原因是什么?

编辑:为澄清起见,我想知道以类似于生成器的方式(一次将一项,而不是全部都存储到内存中)以与Python 2和Python 3兼容的方式遍历字典的正确习惯是什么。 ?

Is it legitimate to use items() instead of iteritems() in all places? Why was iteritems() removed from Python 3? Seems like a terrific and useful method. What’s the reasoning behind it?

Edit: To clarify, I want to know what is the correct idiom for iterating over a dictionary in a generator-like way (one item at a time, not all into memory) in a way that is compatible with both Python 2 and Python 3?


回答 0

在Python 2.x中- .items()返回(键,值)对的列表。在Python 3.x中,.items()现在是一个itemview对象,它的行为有所不同-因此必须对其进行迭代或实例化…因此,list(dict.items())对于dict.items()Python 2.x中的对象来说,这是必需的。

Python 2.7版也有一个有点背口密钥处理的,在你有viewkeysviewitems而且viewvalues方法,最有用的存在viewkeys,其表现更像是一个set(你想从预期dict)。

简单的例子:

common_keys = list(dict_a.viewkeys() & dict_b.viewkeys())

会为您提供常见键的列表,但是同样,在Python 3.x中-只需使用即可.keys()

通常使Python 3.x更加“懒惰”-即map现在有效itertools.imapzipis itertools.izip等等。

In Python 2.x – .items() returned a list of (key, value) pairs. In Python 3.x, .items() is now an itemview object, which behaves different – so it has to be iterated over, or materialised… So, list(dict.items()) is required for what was dict.items() in Python 2.x.

Python 2.7 also has a bit of a back-port for key handling, in that you have viewkeys, viewitems and viewvalues methods, the most useful being viewkeys which behaves more like a set (which you’d expect from a dict).

Simple example:

common_keys = list(dict_a.viewkeys() & dict_b.viewkeys())

Will give you a list of the common keys, but again, in Python 3.x – just use .keys() instead.

Python 3.x has generally been made to be more “lazy” – i.e. map is now effectively itertools.imap, zip is itertools.izip, etc.


回答 1

dict.iteritems之所以被删除是因为dict.items现在它dict.iteritems在python 2.x中做了,甚至通过将它变成了itemview

dict.iteritems was removed because dict.items now does the thing dict.iteritems did in python 2.x and even improved it a bit by making it an itemview.


回答 2

六个库有助于编写与python 2.5+和python 3兼容的代码。它具有iteritems方法,可在python 2和3中使用。示例:

import six

d = dict( foo=1, bar=2 )

for k, v in six.iteritems(d):
    print(k, v)

The six library helps with writing code that is compatible with both python 2.5+ and python 3. It has an iteritems method that will work in both python 2 and 3. Example:

import six

d = dict( foo=1, bar=2 )

for k, v in six.iteritems(d):
    print(k, v)

回答 3

就像python 2python 3的字典文档会告诉您的那样,在python 2中items返回一个列表,而iteritems返回一个迭代器。

在python 3中,items返回view,它与迭代器几乎相同。

如果您使用的是python 2,则可能需要iteritems使用大型字典,而您要做的就是遍历所有项目(不必将它们复制到列表中)

As the dictionary documentation for python 2 and python 3 would tell you, in python 2 items returns a list, while iteritems returns a iterator.

In python 3, items returns a view, which is pretty much the same as an iterator.

If you are using python 2, you may want to user iteritems if you are dealing with large dictionaries and all you want to do is iterate over the items (not necessarily copy them to a list)


回答 4

正如@Wessie指出的,dict.iteritemsdict.iterkeysdict.itervalues(它返回一个迭代中Python2.x)以及dict.viewitemsdict.viewkeysdict.viewvalues(其返回查看对象中Python2.x)均在Python3.x除去

dict.itemsdict.keys并且dict.values曾经用于在Python2.x中返回字典列表的副本,现在返回了Python3.x中的视图对象但是它们仍然与iterator并不相同。

如果要在Python3.x中返回迭代器,请使用iter(dictview)

$ python3.3

>>> d = {'one':'1', 'two':'2'}
>>> type(d.items())
<class 'dict_items'>
>>>
>>> type(d.keys())
<class 'dict_keys'>
>>>
>>>
>>> ii = iter(d.items())
>>> type(ii)
<class 'dict_itemiterator'>
>>>
>>> ik = iter(d.keys())
>>> type(ik)
<class 'dict_keyiterator'>

Just as @Wessie noted, dict.iteritems, dict.iterkeys and dict.itervalues (which return an iterator in Python2.x) as well as dict.viewitems, dict.viewkeys and dict.viewvalues (which return view objects in Python2.x) were all removed in Python3.x

And dict.items, dict.keys and dict.values used to return a copy of the dictionary’s list in Python2.x now return view objects in Python3.x, but they are still not the same as iterator.

If you want to return an iterator in Python3.x, use iter(dictview) :

$ python3.3

>>> d = {'one':'1', 'two':'2'}
>>> type(d.items())
<class 'dict_items'>
>>>
>>> type(d.keys())
<class 'dict_keys'>
>>>
>>>
>>> ii = iter(d.items())
>>> type(ii)
<class 'dict_itemiterator'>
>>>
>>> ik = iter(d.keys())
>>> type(ik)
<class 'dict_keyiterator'>

回答 5

不能使用items,而不是iteritems在所有的Python的地方。例如,以下代码:

class C:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.iteritems()

>>> c = C(dict(a=1, b=2, c=3))
>>> [v for v in c]
[('a', 1), ('c', 3), ('b', 2)]

如果使用,将中断items

class D:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.items()

>>> d = D(dict(a=1, b=2, c=3))
>>> [v for v in d]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __iter__ returned non-iterator of type 'list'

viewitems也是如此,这在Python 3中可用。

同样,由于返回字典对列表的副本(key, value),因此效率较低,除非您仍然要创建副本。

在Python 2中,最好iteritems用于迭代。如果您决定升级到Python 3,2to3可以用该工具替换items

You cannot use items instead iteritems in all places in Python. For example, the following code:

class C:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.iteritems()

>>> c = C(dict(a=1, b=2, c=3))
>>> [v for v in c]
[('a', 1), ('c', 3), ('b', 2)]

will break if you use items:

class D:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.items()

>>> d = D(dict(a=1, b=2, c=3))
>>> [v for v in d]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __iter__ returned non-iterator of type 'list'

The same is true for viewitems, which is available in Python 3.

Also, since items returns a copy of the dictionary’s list of (key, value) pairs, it is less efficient, unless you want to create a copy anyway.

In Python 2, it is best to use iteritems for iteration. The 2to3 tool can replace it with items if you ever decide to upgrade to Python 3.


回答 6

future.utils允许python 2和3兼容性

# Python 2 and 3: option 3
from future.utils import iteritems
heights = {'man': 185,'lady': 165}
for (key, value) in iteritems(heights):
    print(key,value)

>>> ('lady', 165)
>>> ('man', 185)

https://python-future.org/compatible_idioms.html

future.utils allows for python 2 and 3 compatibility

# Python 2 and 3: option 3
from future.utils import iteritems
heights = {'man': 185,'lady': 165}
for (key, value) in iteritems(heights):
    print(key,value)

>>> ('lady', 165)
>>> ('man', 185)

https://python-future.org/compatible_idioms.html