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