¿Existen diferencias aplicables entre dict.items() y dict.iteritems() ?
De los documentos de Python :
dict.items(): Devuelve una copia de la lista de pares (clave, valor) del diccionario.
dict.iteritems(): Devuelve un iterador sobre los pares (clave, valor) del diccionario.
Si ejecuto el siguiente código, cada uno parece devolver una referencia al mismo objeto. ¿Hay diferencias sutiles que me estoy perdiendo?
#!/usr/bin/python d={1:'one',2:'two',3:'three'} print 'd.items():' for k,v in d.items(): if d[k] is v: print '\tthey are the same object' else: print '\tthey are different' print 'd.iteritems():' for k,v in d.iteritems(): if d[k] is v: print '\tthey are the same object' else: print '\tthey are different'Producción:
d.items(): they are the same object they are the same object they are the same object d.iteritems(): they are the same object they are the same object they are the same objectdict.items() devuelve una lista de 2 tuplas ( [(key, value), (key, value), ...] ), mientras que dict.iteritems() es un generador que produce 2 tuplas. El primero ocupa más espacio y tiempo inicialmente, pero el acceso a cada elemento es rápido, mientras que el segundo requiere menos espacio y tiempo inicialmente, pero un poco más de tiempo para generar cada elemento.
Es parte de una evolución.
Originalmente, Python items() creaba una lista real de tuplas y la devolvía. Potencialmente, eso podría requerir mucha memoria adicional.
Luego, los generadores se introdujeron en el lenguaje en general, y ese método se volvió a implementar como un método iterator-generator llamado iteritems() . El original permanece por compatibilidad con versiones anteriores.
Uno de los cambios de Python 3 es que items() ahora devuelven vistas y una list nunca se construye por completo. El método iteritems() también desapareció, ya items() en Python 3 funciona como viewitems() en Python 2.7.
Usted preguntó: '¿Existen diferencias aplicables entre dict.items() y dict.iteritems()'?
Esto puede ayudar (para Python 2.x):
>>> d={1:'one',2:'two',3:'three'} >>> type(d.items()) <type 'list'> >>> type(d.iteritems()) <type 'dictionary-itemiterator'> Puede ver que d.items() devuelve una lista de tuplas de la clave, pares de valores y d.iteritems() devuelve un elemento de diccionario.
Como lista, d.items() se puede segmentar:
>>> l1=d.items()[0] >>> l1 (1, 'one') # an unordered value! Pero no tendría un método __iter__ :
>>> next(d.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: list object is not an iteratorComo iterador, d.iteritems() no se puede segmentar:
>>> i1=d.iteritems()[0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'dictionary-itemiterator' object is not subscriptable Pero tiene __iter__ :
>>> next(d.iteritems()) (1, 'one') # an unordered value!Entonces, los artículos en sí son los mismos: el contenedor que entrega los artículos es diferente. Uno es una lista, el otro un iterador (dependiendo de la versión de Python...)
Entonces, las diferencias aplicables entre dict.items() y dict.iteritems() son las mismas que las diferencias aplicables entre una lista y un iterador.
Los comandos dict.items() , dict.keys() y dict.values() devuelven una copia de la lista del diccionario de pares (k, v) , claves y valores. Esto podría consumir mucha memoria si la lista copiada es muy grande.
Los comandos dict.iteritems() , dict.iterkeys() y dict.itervalues() devuelven un iterador sobre el par, claves y valores del diccionario (k, v) .
Los comandos dict.viewitems() , dict.viewkeys() y dict.viewvalues() devuelven los objetos de vista , que pueden reflejar los cambios del diccionario. (Es decir, si del un elemento o agrega un par (k,v) en el diccionario, el objeto de vista puede cambiar automáticamente al mismo tiempo).
$ python2.7 >>> d = {'one':1, 'two':2} >>> type(d.items()) <type 'list'> >>> type(d.keys()) <type 'list'> >>> >>> >>> type(d.iteritems()) <type 'dictionary-itemiterator'> >>> type(d.iterkeys()) <type 'dictionary-keyiterator'> >>> >>> >>> type(d.viewitems()) <type 'dict_items'> >>> type(d.viewkeys()) <type 'dict_keys'> En Py3.x, las cosas están más limpias, ya que solo están dict.items() , dict.keys() y dict.values() , que devuelven los objetos de vista tal como lo dict.viewitems() en Py2.x .
Tal como señaló @lvc, view object no es lo mismo que iterator , por lo que si desea devolver un iterador en Py3.x, puede usariter(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'>Si usted tiene
dict = {key1:value1, key2:value2, key3:value3,...}
En Python 2 , dict.items() copia cada tupla y devuelve la lista de tuplas en el diccionario, es decir [(key1,value1), (key2,value2), ...] . Las implicaciones son que todo el diccionario se copia en una nueva lista que contiene tuplas
dict = {i: i * 2 for i in xrange(10000000)} # Slow and memory hungry. for key, value in dict.items(): print(key,":",value) dict.iteritems() devuelve el iterador de elementos del diccionario. El valor del elemento devuelto también es el mismo, es decir (key1,value1), (key2,value2), ... , pero esto no es una lista. Este es solo un objeto iterador de elementos de diccionario. Eso significa menos uso de memoria (50% menos).
d.items() -> list(d.items())d.iteritems() -> iter(d.items())Las tuplas son las mismas. Comparaste tuplas en cada uno para obtener lo mismo.
dict = {i: i * 2 for i in xrange(10000000)} # More memory efficient. for key, value in dict.iteritems(): print(key,":",value) En Python 3 , dict.items() devuelve el objeto iterador. dict.iteritems() se elimina por lo que no hay más problemas.
dict.items() devuelve la lista de tuplas, y dict.iteritems() devuelve el objeto iterador de la tupla en el diccionario como (key,value) . Las tuplas son las mismas, pero el contenedor es diferente.
dict.items() básicamente copia todo el diccionario en la lista. Intente usar el siguiente código para comparar los tiempos de ejecución de dict.items() y dict.iteritems() . Verás la diferencia.
import timeit d = {i:i*2 for i in xrange(10000000)} start = timeit.default_timer() #more memory intensive for key,value in d.items(): tmp = key + value #do something like print t1 = timeit.default_timer() - start start = timeit.default_timer() for key,value in d.iteritems(): #less memory intensive tmp = key + value t2 = timeit.default_timer() - startSalida en mi máquina:
Time with d.items(): 9.04773592949 Time with d.iteritems(): 2.17707300186 Esto muestra claramente que dictionary.iteritems() es mucho más eficiente.
dict.iteritems() : te da un iterador. Puede usar el iterador en otros patrones fuera del bucle.
student = {"name": "Daniel", "student_id": 2222} for key,value in student.items(): print(key,value) ('student_id', 2222) ('name', 'Daniel') for key,value in student.iteritems(): print(key,value) ('student_id', 2222) ('name', 'Daniel') studentIterator = student.iteritems() print(studentIterator.next()) ('student_id', 2222) print(studentIterator.next()) ('name', 'Daniel')Si desea una forma de iterar los pares de elementos de un diccionario que funcione con Python 2 y 3, intente algo como esto:
DICT_ITER_ITEMS = (lambda d: d.iteritems()) if hasattr(dict, 'iteritems') else (lambda d: iter(d.items()))Úsalo así:
for key, value in DICT_ITER_ITEMS(myDict): # Do something with 'key' and/or 'value'.dict.iteritems se ha ido en Python3.x Así que use iter(dict.items()) para obtener la misma salida y asignación de memoria
dict.iteritems() en python 2 es equivalente a dict.items() en python 3.