Python2中的dict.items()和dict.iteritems()有什么区别?

问题:Python2中的dict.items()和dict.iteritems()有什么区别?

dict.items()和之间有适用的区别dict.iteritems()吗?

Python文档

dict.items():返回字典的(键,值)对列表的副本

dict.iteritems():在字典的(键,值)对上返回迭代器

如果我运行下面的代码,每个似乎都返回对同一对象的引用。我缺少任何细微的差异吗?

#!/usr/bin/python

d={1:'one',2:'two',3:'three'}
print 'd.items():'
for k,v in d.items():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'

print 'd.iteritems():'   
for k,v in d.iteritems():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'   

输出:

d.items():
    they are the same object
    they are the same object
    they are the same object
d.iteritems():
    they are the same object
    they are the same object
    they are the same object

Are there any applicable differences between dict.items() and dict.iteritems()?

From the Python docs:

dict.items(): Return a copy of the dictionary’s list of (key, value) pairs.

dict.iteritems(): Return an iterator over the dictionary’s (key, value) pairs.

If I run the code below, each seems to return a reference to the same object. Are there any subtle differences that I am missing?

#!/usr/bin/python

d={1:'one',2:'two',3:'three'}
print 'd.items():'
for k,v in d.items():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'

print 'd.iteritems():'   
for k,v in d.iteritems():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'   

Output:

d.items():
    they are the same object
    they are the same object
    they are the same object
d.iteritems():
    they are the same object
    they are the same object
    they are the same object

回答 0

这是演变的一部分。

最初,Python items()构建了一个真正的元组列表,并将其返回。这可能会占用大量额外的内存。

然后,一般将生成器引入该语言,然后将该方法重新实现为名为的迭代器-生成器方法iteritems()。保留原始版本是为了向后兼容。

Python 3的更改之一是 items()现在返回迭代器,并且列表从未完全构建。该iteritems()方法也消失了,因为items()在Python 3中的工作方式与viewitems()在Python 2.7中一样。

It’s part of an evolution.

Originally, Python items() built a real list of tuples and returned that. That could potentially take a lot of extra memory.

Then, generators were introduced to the language in general, and that method was reimplemented as an iterator-generator method named iteritems(). The original remains for backwards compatibility.

One of Python 3’s changes is that items() now return iterators, and a list is never fully built. The iteritems() method is also gone, since items() in Python 3 works like viewitems() in Python 2.7.


回答 1

dict.items()返回2元组([(key, value), (key, value), ...])的列表,而是dict.iteritems()生成2元组的生成器。前者最初占用更多空间和时间,但是访问每个元素的速度很快,而前者最初占用较少的空间和时间,但是在生成每个元素时要花费更多的时间。

dict.items() returns a list of 2-tuples ([(key, value), (key, value), ...]), whereas dict.iteritems() is a generator that yields 2-tuples. The former takes more space and time initially, but accessing each element is fast, whereas the second takes less space and time initially, but a bit more time in generating each element.


回答 2

在Py2.x中

该命令dict.items()dict.keys()dict.values()返回一个副本字典的的列表(k, v)对,键和值。如果复制的列表很大,则可能会占用大量内存。

该命令dict.iteritems()dict.iterkeys()dict.itervalues()返回一个迭代器在字典的(k, v)对,键和值。

该命令dict.viewitems()dict.viewkeys()dict.viewvalues()返回视图对象,它可以体现字典的变化。(即,如果您在字典中del添加了项或(k,v)在字典中添加了对,则视图对象可以同时自动更改。)

$ python2.7

>>> d = {'one':1, 'two':2}
>>> type(d.items())
<type 'list'>
>>> type(d.keys())
<type 'list'>
>>> 
>>> 
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>
>>> type(d.iterkeys())
<type 'dictionary-keyiterator'>
>>> 
>>> 
>>> type(d.viewitems())
<type 'dict_items'>
>>> type(d.viewkeys())
<type 'dict_keys'>

在Py3.x中

在Py3.x,事情比较干净,因为只有dict.items()dict.keys()dict.values()可用,这回该视图对象,就像dict.viewitems()在Py2.x一样。

就像@lvc指出的那样,view对象iterator并不相同,因此,如果要在Py3.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'>

In Py2.x

The commands dict.items(), dict.keys() and dict.values() return a copy of the dictionary’s list of (k, v) pair, keys and values. This could take a lot of memory if the copied list is very large.

The commands dict.iteritems(), dict.iterkeys() and dict.itervalues() return an iterator over the dictionary’s (k, v) pair, keys and values.

The commands dict.viewitems(), dict.viewkeys() and dict.viewvalues() return the view objects, which can reflect the dictionary’s changes. (I.e. if you del an item or add a (k,v) pair in the dictionary, the view object can automatically change at the same time.)

$ python2.7

>>> d = {'one':1, 'two':2}
>>> type(d.items())
<type 'list'>
>>> type(d.keys())
<type 'list'>
>>> 
>>> 
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>
>>> type(d.iterkeys())
<type 'dictionary-keyiterator'>
>>> 
>>> 
>>> type(d.viewitems())
<type 'dict_items'>
>>> type(d.viewkeys())
<type 'dict_keys'>

While in Py3.x

In Py3.x, things are more clean, since there are only dict.items(), dict.keys() and dict.values() available, which return the view objects just as dict.viewitems() in Py2.x did.

But

Just as @lvc noted, view object isn’t the same as iterator, so if you want to return an iterator in Py3.x, you could 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'>

回答 3

您问:“ dict.items()和dict.iteritems()之间是否有适用的区别”

这可能会有所帮助(对于Python 2.x):

>>> d={1:'one',2:'two',3:'three'}
>>> type(d.items())
<type 'list'>
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>

您将看到d.items()返回键,值对的元组列表,并d.iteritems()返回一个字典迭代器。

清单d.items()是可切片的:

>>> l1=d.items()[0]
>>> l1
(1, 'one')   # an unordered value!

但是没有__iter__方法:

>>> next(d.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

作为迭代器,d.iteritems()不可切片:

>>> i1=d.iteritems()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dictionary-itemiterator' object is not subscriptable

但是确实有__iter__

>>> next(d.iteritems())
(1, 'one')               # an unordered value!

因此,物品本身是相同的-运送物品的容器是不同的。一个是列表,另一个是迭代器(取决于Python版本…)

因此,dict.items()和dict.iteritems()之间的适用差异与列表和迭代器之间的适用差异相同。

You asked: ‘Are there any applicable differences between dict.items() and dict.iteritems()’

This may help (for Python 2.x):

>>> d={1:'one',2:'two',3:'three'}
>>> type(d.items())
<type 'list'>
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>

You can see that d.items() returns a list of tuples of the key, value pairs and d.iteritems() returns a dictionary-itemiterator.

As a list, d.items() is slice-able:

>>> l1=d.items()[0]
>>> l1
(1, 'one')   # an unordered value!

But would not have an __iter__ method:

>>> next(d.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

As an iterator, d.iteritems() is not slice-able:

>>> i1=d.iteritems()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dictionary-itemiterator' object is not subscriptable

But does have __iter__:

>>> next(d.iteritems())
(1, 'one')               # an unordered value!

So the items themselves are same — the container delivering the items are different. One is a list, the other an iterator (depending on the Python version…)

So the applicable differences between dict.items() and dict.iteritems() are the same as the applicable differences between a list and an iterator.


回答 4

dict.items()返回元组列表,并dict.iteritems()在字典中返回元组的迭代器对象为(key,value)。元组相同,但容器不同。

dict.items()基本上将所有字典复制到列表中。尝试使用下面的代码的执行时间比较dict.items()dict.iteritems()。您将看到差异。

import timeit

d = {i:i*2 for i in xrange(10000000)}  
start = timeit.default_timer() #more memory intensive
for key,value in d.items():
    tmp = key + value #do something like print
t1 = timeit.default_timer() - start

start = timeit.default_timer()
for key,value in d.iteritems(): #less memory intensive
    tmp = key + value
t2 = timeit.default_timer() - start

在我的机器上输出:

Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186

这清楚地表明这dictionary.iteritems()是非常有效的。

dict.items() return list of tuples, and dict.iteritems() return iterator object of tuple in dictionary as (key,value). The tuples are the same, but container is different.

dict.items() basically copies all dictionary into list. Try using following code to compare the execution times of the dict.items() and dict.iteritems(). You will see the difference.

import timeit

d = {i:i*2 for i in xrange(10000000)}  
start = timeit.default_timer() #more memory intensive
for key,value in d.items():
    tmp = key + value #do something like print
t1 = timeit.default_timer() - start

start = timeit.default_timer()
for key,value in d.iteritems(): #less memory intensive
    tmp = key + value
t2 = timeit.default_timer() - start

Output in my machine:

Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186

This clearly shows that dictionary.iteritems() is much more efficient.


回答 5

如果你有

dict = {key1:value1, key2:value2, key3:value3,...}

Python 2中dict.items()复制每个元组并返回字典中的元组列表,即[(key1,value1), (key2,value2), ...]。这意味着整个字典将被复制到包含元组的新列表中

dict = {i: i * 2 for i in xrange(10000000)}  
# Slow and memory hungry.
for key, value in dict.items():
    print(key,":",value)

dict.iteritems()返回字典项迭代器。返回的项的值也相同,即(key1,value1), (key2,value2), ...,但这不是列表。这只是字典项迭代器对象。这意味着更少的内存使用量(减少了50%)。

  • 列出为可变快照: d.items() -> list(d.items())
  • 迭代器对象: d.iteritems() -> iter(d.items())

元组是相同的。您比较了每个中的元组,因此您得到相同的元组。

dict = {i: i * 2 for i in xrange(10000000)}  
# More memory efficient.
for key, value in dict.iteritems():
    print(key,":",value)

Python 3中dict.items()返回迭代器对象。dict.iteritems()已删除,因此不再有问题。

If you have

dict = {key1:value1, key2:value2, key3:value3,...}

In Python 2, dict.items() copies each tuples and returns the list of tuples in dictionary i.e. [(key1,value1), (key2,value2), ...]. Implications are that the whole dictionary is copied to new list containing tuples

dict = {i: i * 2 for i in xrange(10000000)}  
# Slow and memory hungry.
for key, value in dict.items():
    print(key,":",value)

dict.iteritems() returns the dictionary item iterator. The value of the item returned is also the same i.e. (key1,value1), (key2,value2), ..., but this is not a list. This is only dictionary item iterator object. That means less memory usage (50% less).

  • Lists as mutable snapshots: d.items() -> list(d.items())
  • Iterator objects: d.iteritems() -> iter(d.items())

The tuples are the same. You compared tuples in each so you get same.

dict = {i: i * 2 for i in xrange(10000000)}  
# More memory efficient.
for key, value in dict.iteritems():
    print(key,":",value)

In Python 3, dict.items() returns iterator object. dict.iteritems() is removed so there is no more issue.


回答 6

dict.iteritems在Python3.x中已经不存在了,因此用于iter(dict.items())获得相同的输出和内存分配

dict.iteritems is gone in Python3.x So use iter(dict.items()) to get the same output and memory alocation


回答 7

如果您想要一种方法来迭代同时适用于Python 2和3的字典的项对,请尝试如下操作:

DICT_ITER_ITEMS = (lambda d: d.iteritems()) if hasattr(dict, 'iteritems') else (lambda d: iter(d.items()))

像这样使用它:

for key, value in DICT_ITER_ITEMS(myDict):
    # Do something with 'key' and/or 'value'.

If you want a way to iterate the item pairs of a dictionary that works with both Python 2 and 3, try something like this:

DICT_ITER_ITEMS = (lambda d: d.iteritems()) if hasattr(dict, 'iteritems') else (lambda d: iter(d.items()))

Use it like this:

for key, value in DICT_ITER_ITEMS(myDict):
    # Do something with 'key' and/or 'value'.

回答 8

dict.iteritems():给您一个迭代器。您可以在循环外的其他模式中使用迭代器。

student = {"name": "Daniel", "student_id": 2222}

for key,value in student.items():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

for key,value in student.iteritems():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

studentIterator = student.iteritems()

print(studentIterator.next())
('student_id', 2222)

print(studentIterator.next())
('name', 'Daniel')

dict.iteritems(): gives you an iterator. You may use the iterator in other patterns outside of the loop.

student = {"name": "Daniel", "student_id": 2222}

for key,value in student.items():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

for key,value in student.iteritems():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

studentIterator = student.iteritems()

print(studentIterator.next())
('student_id', 2222)

print(studentIterator.next())
('name', 'Daniel')

回答 9

python 2中的dict.iteritems()与python 3中的dict.items()等效。

dict.iteritems() in python 2 is equivalent to dict.items() in python 3.