Diccionario de Python: ¿son las claves () y los valores () siempre del mismo orden?

312

Parece que las listas devueltas keys()y los values()métodos de un diccionario son siempre un mapeo 1 a 1 (suponiendo que el diccionario no se altere entre llamar a los 2 métodos).

Por ejemplo:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

Si no altera el diccionario entre llamadas keys()y llamadas values(), ¿está mal suponer que el bucle anterior siempre se imprimirá Verdadero? No pude encontrar ninguna documentación que confirme esto.

Jason Coon
fuente
1
En CPython 3.7 (y versiones posteriores, presumiblemente) puede confiar en el orden de iteración de un orden de inserción de coincidencia de diccionario. mail.python.org/pipermail/python-dev/2017-December/151283.html
BallpointBen
@BallpointBen está en CPython 3.6 y superior y en todas las demás implementaciones de Python que comienzan con Python 3.7
Boris

Respuestas:

353

Encontró esto:

Si items(), keys(), values(), iteritems(), iterkeys(), y itervalues()son llamados sin necesidad de modificaciones que intervienen en el diccionario, las listas se corresponden directamente.

En la documentación 2.x y documentación 3.x .

nosklo
fuente
55
aparentemente la declaración en la documentación 3.x es más clara: "el orden de los artículos se corresponderá directamente"
Shaohua Li
44
Este texto falta en la documentación 3.7. Solo puedo suponer que es porque "Dict mantiene el orden de inserción" en 3.7: mail.python.org/pipermail/python-dev/2017-December/151283.html
EliadL
80

Sí, lo que observó es una propiedad garantizada: las claves (), los valores () y los elementos () devuelven listas en orden congruente si el dict no se altera. iterkeys () & c también iteran en el mismo orden que las listas correspondientes.

Alex Martelli
fuente
1
Sin embargo, en caso de que se altere la lista , Pandas dataframeofrece una alternativa en la que los elementos pueden actualizarse o eliminarse, y el orden y las ubicaciones de índice de los elementos en una estructura tipo dict permanecen fijos.
Ville
48

Sí, está garantizado en python 2.x :

Si las vistas de claves, valores y elementos se repiten sin modificaciones intermedias en el diccionario, el orden de los elementos se corresponderá directamente.

Bjorn
fuente
6

Buenas referencias a los documentos. Así es como puede garantizar el pedido, independientemente de la documentación / implementación:

k, v = zip(*d.iteritems())
Sassa NF
fuente
1
En python3.x, use dict.items ()
Good Will
4

De acuerdo con http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objects , los métodos de claves (), valores () y elementos () de un dict devolverán los iteradores correspondientes cuyas órdenes corresponder. Sin embargo, no puedo encontrar una referencia a la documentación oficial de python 2.x para lo mismo.

Por lo que puedo decir, la respuesta es sí, pero solo en Python 3.0+

sykora
fuente
4

Por lo que vale, algunos códigos de producción muy usados ​​que he escrito se basan en esta suposición y nunca tuve un problema con ellos. Sin embargo, sé que eso no lo hace realidad :-)

Si no quiere correr el riesgo, usaría iteritems () si puede.

for key, value in myDictionary.iteritems():
    print key, value
Koen Bok
fuente
-2

No estaba satisfecho con estas respuestas ya que quería asegurarme de que los valores exportados tuvieran el mismo orden, incluso cuando usaban diferentes dictados.

Aquí puede especificar el orden de las teclas por adelantado, los valores devueltos siempre tendrán el mismo orden, incluso si el dict cambia, o si usa un dict diferente.

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]
jlansey
fuente