Когда следует использовать 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.