ChatGPT解决这个技术问题 Extra ChatGPT

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

dict.items()dict.iteritems() 之间是否存在任何适用的差异?

Python docs

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
这基本上是它们计算方式的差异。 items() 一次创建所有项目并返回一个列表。 iteritems() 返回一个生成器——生成器是一个对象,它每次在其上调用 next() 时一次“创建”一个项目。
在您的特定情况下,d[k] is v 将始终返回 True,因为 python 为 -5 到 256 之间的所有整数保留一个整数对象数组:docs.python.org/2/c-api/int.html 当您在该范围内创建一个 int 时,您实际上只是返回对现有的引用对象:>> a = 2; b = 2 >> a is b True 但是,>> a = 1234567890; b = 1234567890 >> a is b False
@the_wolf 我认为最好添加您在问题中引用的文档的python版本。
在 Python 3 中 iteritems() 是否更改为 iter()?上面的文档链接似乎与这个答案不匹配。
不完全是,@GabrielStaples。 iteritems() 从字典 Python 3 中删除,并且没有替代品。然而,为了同样的效果,你确实使用了 iter()。例如 iter(dict.items())。参见 pep 469:python.org/dev/peps/pep-0469

S
ShadowRanger

这是进化的一部分。

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

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

Python 3 的更改之一是 items() 现在返回视图,而 list 永远不会完全构建。 iteritems() 方法也消失了,因为 Python 3 中的 items() 与 Python 2.7 中的 viewitems() 一样工作。


请注意,您错过了进化的一步:Py3 的行为与 iteritems() 不同。它实际上创建了一个完整的序列协议对象,该对象也反映了对 dict 的更改(并且由 dict 本身支持,而不是冗余列表)-它已作为 viewitems() 向后移植到 2.7。
我想更详细地了解这一点,但我的 google-fu 让我失望了。有人可以向我指出可以帮助我更好地理解这一点的文档、文章或资源吗? @lvc?
@Stew PEP 3106 中描述了更改,what's new in python 3.0 中还有更多内容
很抱歉详细说明了这个古老的问题,但我是否正确理解在 Python 2.x 中 iteritems() 总是比 items() 更可取?
@RubenGeert 大多数时候,没关系。对于非常大的字典,它可能更可取。
I
Ignacio Vazquez-Abrams

dict.items() 返回 2 元组 ([(key, value), (key, value), ...]) 的列表,而 dict.iteritems() 是产生 2 元组的生成器。前者最初需要更多的空间和时间,但访问每个元素很快,而第二种最初需要更少的空间和时间,但生成每个元素的时间要多一些。


那为什么每个元素都一样呢?
为什么你会期望它们有所不同?
文档中的“复制”并不意味着复制了元素(如果需要,请使用 copy.deepcopy)。这意味着它是字典项的副本:如果您执行 items = dct.items(),然后通过添加/删除键或 dct[k] = other_v 修改 dct,则 items 将保持不变。
除非明确说明,否则 Python 中的任何内容都不是深拷贝。
@IgnacioVazquez-Abrams - 关于“更多的空间和时间”:字典的大小开始变得重要。假设我有一个“大”字典 {1:'one', 2:'two', ... },我想在网络服务器上对其进行迭代并呈现结果。我应该在多大程度上开始担心为 Python 2.7 选择 .items() 还是 .iteritems()
C
Community

在 Py2.x 中

命令 dict.items()dict.keys()dict.values() 返回字典的 list (k, v) 对、键和值的副本。如果复制的列表非常大,这可能会占用大量内存。

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

命令 dict.viewitems()dict.viewkeys()dict.viewvalues() 返回 view objects,它可以反映字典的更改。 (即,如果您在字典中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() 可用,它们返回 视图对象,就像 Py2.x 中的 dict.viewitems() 一样。

正如@lvc 所说,view objectiterator 不同,所以如果你想在 Py3.x 中返回一个 iterator,你可以使用 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'>

d
dawg

你问:'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() 之间的适用差异与列表和迭代器之间的适用差异相同。


P
Prabhu

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() 效率更高。


F
Framester

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


H
Hary Bakta

如果你有

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() 已删除,因此不再有问题。


e
ethplumber

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')

u
user128364

python 2 中的 dict.iteritems() 等价于 python 3 中的 dict.items()。


这是不正确的。之前的答案中已经解释了差异。