Kiedy powinno się używać iteritems () zamiast items ()?


153

Czy używanie items()zamiast iteritems()wszędzie jest uzasadnione ? Dlaczego został iteritems()usunięty z Pythona 3? Wydaje się świetną i przydatną metodą. Jaki jest tego powód?

Edycja: Aby wyjaśnić, chcę wiedzieć, jaki jest poprawny idiom do iteracji po słowniku w sposób podobny do generatora (jeden element na raz, nie wszystkie do pamięci) w sposób zgodny zarówno z Pythonem 2, jak i Pythonem 3 ?

Odpowiedzi:


148

W Pythonie 2.x - .items()zwróciło listę par (klucz, wartość). W Pythonie 3.x .items()jest teraz itemviewobiektem, który zachowuje się inaczej - więc musi być iterowany lub zmaterializowany ... Tak więc list(dict.items())jest wymagany do tego, co było dict.items()w Pythonie 2.x.

Python 2.7 ma także trochę back-port dla klucza obchodzenia się, że masz viewkeys, viewitemsa viewvaluesmetody, najbardziej przydatne istota viewkeys, która zachowuje się bardziej jak set(co można oczekiwać od A dict).

Prosty przykład:

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

Wyświetli listę typowych kluczy, ale znowu, w Pythonie 3.x - po prostu użyj .keys()zamiast tego.

Python 3.x jest generalnie bardziej „leniwy” - mapto znaczy jest teraz efektywny itertools.imap, zipjest itertools.izipitd.


96

dict.iteritemszostał usunięty, ponieważ dict.itemsteraz robi to dict.iteritemssamo w Pythonie 2.x, a nawet ulepszył go nieco, zmieniając plik itemview.


64

Sześć bibliotek pomaga w pisaniu kodu, który jest kompatybilny zarówno z Pythonem 2.5+, jak i Pythonem 3. Posiada metodę iteritems, która będzie działać zarówno w Pythonie 2, jak i 3. Przykład:

import six

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

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

9

Jak powie Ci dokumentacja słownika dla pythona 2 i pythona 3 , w pythonie 2 itemszwraca listę, a iteritemszwraca iterator.

W Pythonie 3 itemszwraca widok , który jest prawie taki sam jak iterator.

Jeśli używasz Pythona 2, możesz chcieć user, iteritemsjeśli masz do czynienia z dużymi słownikami i wszystko, co chcesz zrobić, to iterować po elementach (niekoniecznie kopiować je na listę)


Rozumiem, że iteritemsto iterator, dlatego jest tak przydatny. Prawie nigdy nie chcę przeglądać słownika jako listy. Więc jaki jest właściwy sposób iteracji słownika z generatorem w sposób zgodny zarówno z Pythonem 2, jak i 3?

3
@ user248237 for key in some_dictdziała na obu - a 2to3narzędzie i tak przetłumaczy iteritems()na items()...
Jon Clements

1
@JonClements: w porządku, chociaż zawsze uważałem, że for k in d: d[k]jest niepotrzebnie gadatliwy / niepytoniczny

6

Podobnie jak zauważyć @Wessie, dict.iteritems, dict.iterkeysi dict.itervalues(które zwracają iterację w Python2.x), jak również dict.viewitems, dict.viewkeysoraz dict.viewvalues(co powrót widok obiektów w Python2.x) były usunięte w Python3.x

A dict.items, dict.keysi dict.valuesużywany do zwracania kopię listy słownika w Python2.x teraz powrócić Wyświetlanie obiektów w Python3.x, ale nie są one jeszcze tak samo jak iteratora .

Jeśli chcesz zwrócić iterator w Python3.x, użyj 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'>

Co jest bardziej wydajne, gdy chce się przeprowadzić wyszukiwanie odwrotne? przeglądać obiekty czy iterator?
Lifebalance

6

Nie możesz używać itemszamiast tego iteritemswe wszystkich miejscach w Pythonie. Na przykład następujący kod:

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)]

zepsuje się, jeśli użyjesz 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'

To samo dotyczy viewitems , które jest dostępne w Pythonie 3.

Ponadto, ponieważ elementy zwracają kopię listy (key, value)par ze słownika , jest to mniej wydajne, chyba że i tak chcesz utworzyć kopię.

W Pythonie 2 najlepiej używać go iteritemsdo iteracji. 2to3Narzędzie może zastąpić go items, jeśli kiedykolwiek zdecydujesz się na uaktualnienie do Python 3.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.