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

the*_*olf 673 python dictionary python-2.x

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'   
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

Kei*_*ith 826

这是进化的一部分.

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

然后,生成器被引入到该语言中,并且该方法被重新实现为名为的迭代器生成器方法iteritems().原始保留了向后兼容性.

Python 3的一个变化是 items()现在返回迭代器,并且列表永远不会完全构建.该iteritems()方法也已消失,因为items()Python 3的工作方式与viewitems()Python 2.7 类似.

  • 请注意,您错过了演变中的一个步骤:Py3行为与`iteritems()`不同.它实际上是一个完整的序列协议对象,它也反映了对dict的更改(并且由dict本身支持,而不是冗余列表) - 它被反向移植到2.7作为`viewitems()`. (156认同)
  • @Stew [PEP 3106](https://www.python.org/dev/peps/pep-3106/)中描述了这一变化,[python 3.0中的新功能]还有更多内容(https:// docs.python.org/3/whatsnew/3.0.html#views-and-iterators-instead-of-lists) (9认同)
  • 我想更详细地了解这一点,但是我的google-fu让我失望了.有人能指出我可以帮助我更好地理解这一点的文档,文章或来源吗?@lvc? (3认同)
  • @RubenGeert大多数时候,没关系.对于非常大的dicts,它可能更好. (2认同)

Ign*_*ams 93

dict.items()返回一个2元组([(key, value), (key, value), ...])的列表,而是dict.iteritems()一个产生2元组的生成器.前者需要更多的空间和时间开始,但是访问每个元件是快速的,而第二占用较少的空间和时间开始,但更多的时间在生成的每个元素.

  • 你为什么期望他们与众不同? (9认同)
  • 除非明确记录,否则Python中的任何内容都不是深层副本. (4认同)
  • 文档中的"副本"并不意味着复制了元素(如果需要,请使用`copy.deepcopy`).这意味着它是字典项的副本:如果你执行`items = dct.items()`然后通过添加/删除键或`dct [k] = other_v`修改`dct`,`items`将保留相同. (3认同)

YaO*_*OzI 63

在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'>
Run Code Online (Sandbox Code Playgroud)

而在Py3.x中

在Py3.x中,事情更加干净,因为只有dict.items(),dict.keys()并且dict.values()可用,它们返回视图对象,就像dict.viewitems()在Py2.x中一样.

就像@lvc指出的那样,view对象迭代器不同,所以如果你想在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'>
Run Code Online (Sandbox Code Playgroud)


daw*_*awg 33

你问:'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'>
Run Code Online (Sandbox Code Playgroud)

您可以看到d.items()返回键,值对的元组列表并d.iteritems()返回字典itemiterator.

作为列表,d.items()是可切片的:

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

但是没有__iter__方法:

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

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

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

但确实有__iter__:

>>> next(d.iteritems())
(1, 'one')               # an unordered value!
Run Code Online (Sandbox Code Playgroud)

所以物品本身是相同的 - 提供物品的容器是不同的.一个是列表,另一个是迭代器(取决于Python版本......)

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


Pra*_*bhu 13

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
Run Code Online (Sandbox Code Playgroud)

我的机器输出:

Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186
Run Code Online (Sandbox Code Playgroud)

这清楚地表明dictionary.iteritems()效率更高.


Tes*_*ter 11

dict.iteritems在 Python3.x 中消失了所以用于iter(dict.items())获取相同的输出和内存分配