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


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если вы имеете дело с большими словарями, и все, что вам нужно сделать, - это перебирать элементы (не обязательно копировать их в список)


Я понимаю, что 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'>

Что является более эффективным, когда кто-то хочет сделать обратный поиск? просмотреть объекты или итератор?
спасательный круг

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.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.