Ok, entonces puedo usar un OrderedDict en json.dump
. Es decir, un OrderedDict se puede usar como entrada para JSON.
Pero, ¿se puede usar como salida? ¿Si es así, cómo? En mi caso, me gustaría load
ingresar en un OrderedDict para poder mantener el orden de las claves en el archivo.
Si no, ¿hay algún tipo de solución?
python
json
load
ordereddictionary
c00kiemonster
fuente
fuente
json.load
para usar OrderedDicts en lugar de Dicts en Python.Respuestas:
Sí tu puedes. Al especificar el
object_pairs_hook
argumento a JSONDecoder . De hecho, este es el ejemplo exacto dado en la documentación.Puede pasar este parámetro a
json.loads
(si no necesita una instancia de Decoder para otros fines) así:El uso
json.load
se realiza de la misma manera:fuente
object_pairs_hook
lugar de "cada par se pasará a object_pairs_hook",json.load
no lo mantiene ordenado de manera predeterminada, pero parece que solo refleja lo que hace json en sí mismo:{}
están desordenados, pero[]
en json están ordenados como se describe aquíOrderedDict
se usará para generar el valor resultante de python.Versión simple para Python 2.7+
O para Python 2.4 a 2.6
fuente
simplejson
yordereddict
son bibliotecas separadas que necesita instalar.loads('{}', object_pairs_hook=OrderedDict)
.Algunas buenas noticias! Desde la versión 3.6, la implementación de cPython ha preservado el orden de inserción de los diccionarios ( https://mail.python.org/pipermail/python-dev/2016-September/146327.html ). Esto significa que la biblioteca json ahora conserva el orden de forma predeterminada. Observe la diferencia de comportamiento entre python 3.5 y 3.6. El código:
En py3.5 el orden resultante no está definido:
En la implementación de cPython de python 3.6:
La gran noticia es que esto se ha convertido en una especificación de lenguaje a partir de python 3.7 (en oposición a un detalle de implementación de cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283 .html
Entonces la respuesta a su pregunta ahora es: ¡actualice a Python 3.6! :)
fuente
json.loads('{"2": 2, "1": 1}')
vuelve{'1': 1, '2': 2}
para mí.dict.__repr__
ordena las teclas mientras se conserva el orden subyacente. En otras palabras,json.loads('{"2": 2, "1": 1}').items()
esdict_items([('2', 2), ('1', 1)])
incluso sirepr(json.loads('{"2": 2, "1": 1}'))
es"{'1': 1, '2': 2}"
.¿Siempre podría escribir la lista de claves además de eliminar el dict y luego reconstruirlo
OrderedDict
iterando a través de la lista?fuente
OrdereDict
s.Además de volcar la lista ordenada de claves junto con el diccionario, otra solución de baja tecnología, que tiene la ventaja de ser explícita, es volcar la lista (ordenada) de pares clave-valor
ordered_dict.items()
; cargar es un simpleOrderedDict(<list of key-value pairs>)
. Esto maneja un diccionario ordenado a pesar de que JSON no tiene este concepto (los diccionarios JSON no tienen orden).De hecho, es bueno aprovechar el hecho de que
json
volca el OrderedDict en el orden correcto. Sin embargo, en general es innecesariamente pesado y no necesariamente significativo tener que leer todos los diccionarios JSON como un OrderedDict (a través delobject_pairs_hook
argumento), por lo que una conversión explícita de solo los diccionarios que deben ordenarse también tiene sentido.fuente
El comando de carga usado normalmente funcionará si especifica el parámetro object_pairs_hook :
fuente