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
答案 0 :(得分:773)
这是进化的一部分。
最初,Python items()
构建了一个真实的元组列表并返回了它。这可能会占用大量额外的内存。
然后,生成器被引入到该语言中,并且该方法被重新实现为名为iteritems()
的迭代器生成器方法。原始保留了向后兼容性。
Python 3的一个变化是items()
现在返回迭代器,并且列表永远不会完全构建。 iteritems()
方法也已消失,因为Python 3中的items()
与Python 2.7中的viewitems()
类似。
答案 1 :(得分:90)
dict.items()
返回2元组列表([(key, value), (key, value), ...]
),而dict.iteritems()
是生成2元组的生成器。前者最初需要更多的空间和时间,但访问每个元素的速度很快,而第二个元素最初占用的空间和时间较少,但生成每个元素的时间要多一些。
答案 2 :(得分:61)
命令dict.items()
,dict.keys()
和dict.values()
会返回字典的列表 (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中,事情更干净,因为只有dict.items()
,dict.keys()
和dict.values()
可用,它们返回视图对象 Py2.x中的dict.viewitems()
做了。
正如@lvc所说,查看对象与迭代器不同,所以如果你想在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'>
答案 3 :(得分:32)
您问:'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()
返回字典 - itemiterator。
作为列表,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()之间的适用差异与列表和迭代器之间的适用差异相同。
答案 4 :(得分: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
我的机器输出:
Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186
这清楚地表明dictionary.iteritems()
效率更高。
答案 5 :(得分:4)
如果你有
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(),因此不再有问题。
答案 6 :(得分:0)
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')
答案 7 :(得分:0)
如果您想要一种方法来迭代同时适用于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'.
答案 8 :(得分:0)
dict.iteritems
在Python3.x中已消失,因此请使用iter(dict.iitems())
获得相同的输出和内存分配
答案 9 :(得分:-3)
dict.iteritems()等效于python 3中的dict.items()。