python python-3.x

iteritems en Python



python-3.x (6)

Como la documentación del diccionario para python 2 y python 3 le diría, en python 2 items devuelve una lista, mientras que iteritems devuelve un iterador.

En python 3, items devuelve una view , que es más o menos lo mismo que un iterador.

Si está utilizando Python 2, puede iteritems si está tratando con diccionarios grandes y todo lo que desea hacer es iterar sobre los elementos (no necesariamente copiarlos en una lista)

¿Es legítimo usar items() lugar de iteritems() en todos los lugares? ¿Por qué se iteritems() de Python 3? Parece un método excelente y útil. ¿Cuál es el razonamiento detrás de esto?

EDITAR: Para aclarar, quiero saber cuál es el modismo correcto para iterar sobre un diccionario de forma similar a un generador (un elemento a la vez, no todo en la memoria) de una manera que sea compatible con Python 2 y Python 3 ?


En Python 2.x - .items() devolvió una lista de pares (clave, valor). En Python 3.x, .items() ahora es un objeto itemview , que se comporta de manera diferente, por lo que debe repetirse o materializarse ... Por lo tanto, list(dict.items()) es obligatorio para lo que era dict.items() en Python 2.x.

Python 2.7 también tiene un poco de back-port para el manejo de claves, ya que tiene los viewkeys , viewitems y viewvalues , los más útiles son las viewkeys que se comportan más como un set (lo que se esperaría de un dict ).

Ejemplo simple:

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

Le dará una lista de las claves comunes, pero nuevamente, en Python 3.x - simplemente use .keys() lugar.

Python 3.x generalmente se ha hecho para ser más "flojo", es decir, el map ahora es itertools.imap , zip es itertools.izip , etc.


No puede usar items en iteritems lugar iteritems en todos los lugares de Python. Por ejemplo, el siguiente código:

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

se romperá si usa 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''

Lo mismo es cierto para viewitems , que está disponible en Python 3.

Además, dado que los .items() devuelven una copia de la lista del diccionario de pares (key, value) , es menos eficiente, a menos que desee crear una copia de todos modos.

En Python 2, es mejor usar iteritems para la iteración. La herramienta 2to3 puede reemplazarla con items si alguna vez decides actualizar a Python 3.


Tal como lo señaló @Wessie, dict.iteritems , dict.iterkeys y dict.itervalues (que devuelven un iterador en Python2.x), así como dict.viewitems , dict.viewkeys y dict.viewvalues (que devuelven objetos de vista en Python2.x ) fueron eliminados en Python3.x

Y dict.items , dict.keys y dict.values utilizados para devolver una copia de la lista del diccionario en Python2.x ahora devuelven objetos de vista en Python3.x, pero todavía no son lo mismo que iterator .

Si desea devolver un iterador en Python3.x, use 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''>


La biblioteca de seis ayuda a escribir código que es compatible tanto con python 2.5+ como con python 3. Tiene un método iteritems que funcionará tanto en python 2 como en 3. Ejemplo:

from __future__ import division, absolute_import, print_function, unicode_literals import six d = dict( foo=1, bar=2 ) for k, v in six.iteritems(d): print(k, v)


dict.iteritems se eliminó porque dict.items ahora hace lo que dict.iteritems hizo en python 2.x e incluso lo mejoró un poco haciéndolo una itemview .