Когда следует использовать iteritems() вместо items()?

iteritems() ли использовать items() вместо iteritems() во всех местах? Почему iteritems() удален из Python 3? Похоже, потрясающий и полезный метод. Каковы причины этого?

Изменить: Чтобы уточнить, я хочу знать, какова правильная идиома для итераций по словарю в генераторной манере (один элемент за раз, не все в памяти) таким образом, который совместим как с Python 2 и Python 3?

Ответ 1

В Python 2.x - .items() вернулся список пар (ключ, значение). В Python 3.x .items() теперь является объектом itemview, который ведет себя по-другому - поэтому он имеет, чтобы повторить, или материализованы... Итак, list(dict.items()) требуется для того, что было dict.items() в Python 2.x.

Python 2.7 также имеет немного обратного порта для обработки ключей, поскольку у вас viewkeys, viewitems и viewvalues, наиболее полезным является viewkeys, который ведет себя как set (который вы ожидаете от dict).

Простой пример:

common_keys = list(dict_a.viewkeys() & dict_b.viewkeys())

Дает вам список общих ключей, но опять же, в Python 3.x - просто используйте .keys().

Python 3.x обычно делается более "ленивым" - т.е. map теперь эффективно itertools.imap, zip itertools.izip и т.д.

Ответ 2

dict.iteritems был удален, потому что dict.items теперь делает вещь dict.iteritems в python 2.x и даже немного улучшила ее, сделав ее itemview.

Ответ 3

Шесть библиотек помогают в написании кода, который совместим как с python 2. 5+, так и с python 3. У нее есть метод iteritems, который будет работать как в python 2, так и в 3. Пример:

import six

d = dict( foo=1, bar=2 )

for k, v in six.iteritems(d):
    print(k, v)

Ответ 4

Поскольку словарная документация для python 2 и python 3 скажет вам, в python 2 items возвращают список, а iteritems возвращает итератор.

В python 3 items возвращают представление, которое в значительной степени совпадает с итератором.

Если вы используете python 2, вы можете захотеть использовать iteritems для пользователя, если имеете дело с большими словарями, и все, что вы хотите сделать, это перебрать элементы (не обязательно скопировать их в список)

Ответ 5

Как заметил @Wessie, dict.iteritems, dict.iterkeys и dict.itervalues (которые возвращают итератор в Python2.x), а также dict.viewitems, dict.viewkeys и dict.viewvalues (которые возвращают объекты представления в Python2.x ) все были удалены в Python3.x

А dict.items, dict.keys и dict.values используемые для возврата копии списка словарей в Python2.x, теперь возвращают объекты представления в Python3.x, но они все равно не совпадают с итераторами.

Если вы хотите вернуть итератор в Python3.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'>

Ответ 6

Вы не можете использовать items вместо iteritems во всех местах Python. Например, следующий код:

class C:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.iteritems()

>>> c = C(dict(a=1, b=2, c=3))
>>> [v for v in c]
[('a', 1), ('c', 3), ('b', 2)]

сломается, если вы используете items:

class D:
  def __init__(self, a):
    self.a = a
  def __iter__(self):
    return self.a.items()

>>> d = D(dict(a=1, b=2, c=3))
>>> [v for v in d]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __iter__ returned non-iterator of type 'list'

То же самое относится и к элементам представления, которые доступны в Python 3.

Кроме того, поскольку items возвращает копию списка словарей из пар (key, value), это менее эффективно, если вы не хотите создавать копию в любом случае.

В Python 2 лучше всего использовать iteritems для итерации. Инструмент 2to3 может заменить его на items, если вы когда-нибудь решите перейти на Python 3.