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

153

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

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

Мартино
источник

Ответы:

148

В 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и т. Д.

Джон Клементс
источник
96

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

Wessie
источник
64

Шесть библиотек помогают в написании кода, который совместим как с 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)
Декан сереневый
источник
9

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

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

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

goncalopp
источник
Я понимаю, что iteritemsэто итератор, поэтому он так полезен. Я почти никогда не хочу перебирать словарь как список. Итак, как правильно перебирать словарь с помощью генератора, совместимого с Python 2 и 3?
3
@ user248237 for key in some_dictработает на обоих - и 2to3инструмент будет переводить iteritems()в items()любом случае ...
Джон Клементс
1
@JonClements: достаточно справедливо, хотя я всегда думал, что for k in d: d[k]это излишне многословно / непифонично
6

Подобно тому , как отмечено @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'>
YaOzI
источник
Что является более эффективным, когда кто-то хочет сделать обратный поиск? просмотреть объекты или итератор?
спасательный круг
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.

Флориан Зима
источник
0

future.utils обеспечивает совместимость с python 2 и 3

# Python 2 and 3: option 3
from future.utils import iteritems
heights = {'man': 185,'lady': 165}
for (key, value) in iteritems(heights):
    print(key,value)

>>> ('lady', 165)
>>> ('man', 185)

https://python-future.org/compatible_idioms.html

Даниил
источник