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
.