В чем разница между 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

Ответ 1

Это часть эволюции.

Первоначально Python items() построил реальный список кортежей и вернул его. Это потенциально может занять много дополнительной памяти.

Затем генераторы были введены в язык вообще, и этот метод был переопределен как метод итератора-генератора с именем iteritems(). Оригинал остается для обратной совместимости.

Один из изменений Python 3s заключается в том, что items() теперь возвращают итераторы, и список никогда не строится полностью. Метод iteritems() также исчез, так как items() в Python 3 работает как viewitems() в Python 2.7.

Ответ 2

dict.items() возвращает список 2-кортежей ([(key, value), (key, value), ...]), тогда как dict.iteritems() - это генератор, который дает 2-кортежи. Первый изначально занимает больше места и времени, но доступ к каждому элементу происходит быстро, тогда как второй занимает меньше места и времени изначально, но немного больше времени для генерации каждого элемента.

Ответ 3

В Py2.x

Команды dict.items(), dict.keys() и dict.values() возвращают копию словаря список из (k, v) пары, ключей и значений. Это может занять много памяти, если скопированный список очень большой.

Команды dict.iteritems(), dict.iterkeys() и dict.itervalues() возвращают итератор по парам, клавишам и значениям словарей (k, v).

Команды dict.viewitems(), dict.viewkeys() и dict.viewvalues() возвращают объекты просмотра, которые могут отражать словарь изменяется. (I.e. если вы 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, объект просмотра не совпадает с итератором, поэтому, если вы хотите вернуть 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'>

Ответ 4

Вы спросили: "Существуют ли какие-либо применимые различия между 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() может быть slice-able:

>>> 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() совпадают с применимыми различиями между списком и итератором.

Ответ 5

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() намного эффективнее.

Ответ 6

Если у вас

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

В Python 2, dict.items() копирует каждый кортеж и возвращает список кортежей в словаре i.e. [(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() возвращает итератор позиции словаря. Значение возвращаемого элемента также совпадает с i.e. (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() удаляется, поэтому проблем больше нет.

Ответ 7

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

Ответ 8

Если вам нужен способ итерации пар элементов словаря, который работает с 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'.

Ответ 9

dict.iteritems отсутствует в Python3.x Поэтому используйте iter(dict.iitems()) чтобы получить тот же вывод и распределение памяти

Ответ 10

dict.iteritems() в python 2 эквивалентен dict.items() в python 3.