python - sumar - Diccionarios: ¿Cómo mantener las claves/valores en el mismo orden en que fueron declarados?
recorrer diccionario python (10)
Tengo un diccionario que declaré en un orden particular y quiero mantenerlo en ese orden todo el tiempo. Las claves / valores realmente no se pueden mantener en orden según su valor, solo lo quiero en el orden en que lo declaré.
Así que si tengo el diccionario:
d = {''ac'': 33, ''gw'': 20, ''ap'': 102, ''za'': 321, ''bs'': 10}
No está en ese orden si lo veo o lo repito, ¿hay alguna forma de asegurarse de que Python mantendrá el orden explícito en el que declaré las claves / valores?
Desde Python 3.6 en adelante, el tipo de dict
estándar mantiene el orden de inserción por defecto.
Definiendo
d = {''ac'':33, ''gw'':20, ''ap'':102, ''za'':321, ''bs'':10}
resultará en un diccionario con las claves en el orden indicado en el código fuente.
Esto se logró mediante el uso de una matriz simple con enteros para la tabla hash dispersa, donde esos enteros se indexan en otra matriz que almacena los pares clave-valor (más el hash calculado). La última matriz simplemente almacena los elementos en orden de inserción, y la combinación completa en realidad usa menos memoria que la implementación utilizada en Python 3.5 y anteriores. Vea la idea original publicada por Raymond Hettinger para más detalles.
En 3.6 esto todavía se consideraba un detalle de implementación; Consulte la documentación de Novedades en Python 3.6 :
El aspecto de conservación de orden de esta nueva implementación se considera un detalle de implementación y no se debe confiar en él (esto puede cambiar en el futuro, pero se desea tener esta nueva implementación de dictado en el idioma para algunas versiones antes de cambiar la especificación de idioma). para ordenar la semántica de preservación de órdenes para todas las implementaciones actuales y futuras de Python, esto también ayuda a preservar la compatibilidad con versiones anteriores del lenguaje en el que el orden de iteración aleatorio sigue vigente, por ejemplo, Python 3.5).
Python 3.7 eleva este detalle de implementación a una especificación de lenguaje , por lo que ahora es obligatorio que dict
orden en todas las implementaciones de Python compatibles con esa versión o más nueva. Ver el pronunciamiento de la BDFL .
Es posible que aún desee utilizar la clase collections.OrderedDict()
en ciertos casos, ya que ofrece algunas funciones adicionales además del tipo de dict
estándar. Como ser reversible (esto se extiende a los objetos de la vista ), y la reordenación compatible (a través del método move_to_end()
).
En general, puede diseñar una clase que se comporte como un diccionario, principalmente implementando los métodos __contains__
, __getitem__
, __delitem__
, __setitem__
y algunos más. Esa clase puede tener el comportamiento que desee, por ejemplo, dividir un iterador ordenado sobre las teclas ...
En lugar de explicar la parte teórica, daré un ejemplo simple.
>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary[''foo'']=3
>>> my_dictionary[''aol'']=1
>>> my_dictionary
OrderedDict([(''foo'', 3), (''aol'', 1)])
>>> dict(my_dictionary)
{''foo'': 3, ''aol'': 1}
Los diccionarios utilizarán un orden que hace que la búsqueda sea eficiente, y usted no puede cambiar eso,
Solo puede usar una lista de objetos (una tupla de 2 elementos en un caso simple, o incluso una clase), y agregar elementos al final. A continuación, puede utilizar la búsqueda lineal para encontrar elementos en él.
Alternativamente, puede crear o usar una estructura de datos diferente creada con la intención de mantener el orden.
Me topé con este post mientras trataba de averiguar cómo hacer que OrderedDict funcionara. PyDev para Eclipse no pudo encontrar OrderedDict en absoluto, así que decidí hacer una tupla de los valores clave de mi diccionario como me gustaría que fueran ordenados. Cuando tuve que mostrar mi lista, simplemente iteré a través de los valores de la tupla y conecté la ''clave'' iterada de la tupla al diccionario para recuperar mis valores en el orden en que los necesitaba.
ejemplo:
test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( ''val1'', ''val2'', ''val3'', ''val4'')
for key in test_tuple: print(test_dict[key])
Es un poco engorroso, pero estoy presionado por el tiempo y es la solución que se me ocurrió.
nota: el enfoque de lista de listas que alguien más sugirió no tiene sentido para mí, porque las listas están ordenadas e indexadas (y también son una estructura diferente a los diccionarios).
Realmente no puedes hacer lo que quieres con un diccionario. Ya tienes el diccionario d = {''ac'':33, ''gw'':20, ''ap'':102, ''za'':321, ''bs'':10}
creado. Descubrí que no había forma de mantenerse en orden una vez que ya está creado. Lo que hice fue hacer un archivo json con el objeto:
{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}
Solía:
r = json.load(open(''file.json''), object_pairs_hook=OrderedDict)
luego se utiliza:
print json.dumps(r)
para verificar.
Si desea tener un diccionario en un orden específico, también puede crear una lista de listas, donde el primer elemento será la clave, y el segundo será el valor y se verá como este ejemplo.
>>> list =[[1,2],[2,3]]
>>> for i in list:
... print i[0]
... print i[1]
1
2
2
3
Tuve un problema similar al desarrollar un proyecto Django. No pude usar OrderedDict, porque estaba ejecutando una versión antigua de python, por lo que la solución simple era usar la clase SortedDict de Django:
Tenga en cuenta que esta respuesta se aplica a las versiones de python anteriores a python3.7. CPython 3.6 mantiene el orden de inserción en la mayoría de las circunstancias como un detalle de implementación. A partir de Python3.7 en adelante, se ha declarado que las implementaciones DEBEN mantener el orden de inserción para ser compatibles.
Los diccionarios de Python están desordenados. Si desea un diccionario ordenado, intente collections.OrderedDict .
Tenga en cuenta que OrderedDict se introdujo en la biblioteca estándar en Python 2.7. Si tiene una versión anterior de python, puede encontrar recetas para diccionarios ordenados en ActiveState .
from collections import OrderedDict
OrderedDict((word, True) for word in words)
contiene
OrderedDict([(''He'', True), (''will'', True), (''be'', True), (''the'', True), (''winner'', True)])
Si los valores son True
(o cualquier otro objeto inmutable), también puede usar:
OrderedDict.fromkeys(words, True)