Ok, donc je peux utiliser un OrderedDict dans json.dump
. Autrement dit, un OrderedDict peut être utilisé comme entrée pour JSON.
Mais peut-il être utilisé comme sortie? Si c'est le cas, comment? Dans mon cas, j'aimeraisload
entrer dans un OrderedDict afin que je puisse conserver l'ordre des clés dans le fichier.
Sinon, existe-t-il une sorte de solution?
python
json
load
ordereddictionary
c00kiemonster
la source
la source
json.load
pour utiliser OrderedDicts au lieu de Dicts en Python.Réponses:
Oui, vous pouvez. En spécifiant l'
object_pairs_hook
argument à JSONDecoder . En fait, c'est l'exemple exact donné dans la documentation.Vous pouvez passer ce paramètre à
json.loads
(si vous n'avez pas besoin d'une instance de Decoder à d'autres fins) comme ceci:L'utilisation
json.load
se fait de la même manière:la source
object_pairs_hook
, plutôt que "chaque paire sera transmise à object_pairs_hook,"json.load
cela ne le maintient pas ordonné par défaut, mais il semble que cela ne fait que refléter ce que fait json lui-même - les commandes ne{}
sont pas ordonnées, mais les commandes[]
dans le json sont commandées comme décrit iciOrderedDict
sera utilisé pour créer la valeur python résultante.Version simple pour Python 2.7+
Ou pour Python 2.4 à 2.6
la source
simplejson
et ceordereddict
sont des bibliothèques distinctes que vous devez installer.loads('{}', object_pairs_hook=OrderedDict)
.De bonnes nouvelles! Depuis la version 3.6, l'implémentation de cPython a conservé l'ordre d'insertion des dictionnaires ( https://mail.python.org/pipermail/python-dev/2016-September/146327.html ). Cela signifie que la bibliothèque json conserve désormais l'ordre par défaut. Observez la différence de comportement entre python 3.5 et 3.6. Le code:
Dans py3.5, l'ordre résultant n'est pas défini:
Dans l'implémentation cPython de python 3.6:
La très bonne nouvelle est que c'est devenu une spécification de langage à partir de python 3.7 (par opposition à un détail d'implémentation de cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283 .html
La réponse à votre question devient alors: passer à python 3.6! :)
la source
json.loads('{"2": 2, "1": 1}')
devient{'1': 1, '2': 2}
pour moi.dict.__repr__
clés de tri tandis que l'ordre sous-jacent est préservé. En d'autres termes,json.loads('{"2": 2, "1": 1}').items()
c'estdict_items([('2', 2), ('1', 1)])
même sirepr(json.loads('{"2": 2, "1": 1}'))
c'est le cas"{'1': 1, '2': 2}"
.Vous pouvez toujours écrire la liste des clés en plus de vider le dict, puis reconstruire le
OrderedDict
en itérant dans la liste?la source
OrdereDict
art.En plus de vider la liste ordonnée de clés à côté du dictionnaire, une autre solution de faible technologie, qui a l'avantage d'être explicite, consiste à vider la liste (ordonnée) de paires clé-valeur
ordered_dict.items()
; le chargement est simpleOrderedDict(<list of key-value pairs>)
. Cela gère un dictionnaire ordonné malgré le fait que JSON n'a pas ce concept (les dictionnaires JSON n'ont pas d'ordre).Il est en effet agréable de profiter du fait que les
json
dumps OrderedDict dans le bon ordre. Cependant, il est en général inutilement lourd et pas nécessairement significatif d'avoir à lire tous les dictionnaires JSON en tant que OrderedDict (à travers l'object_pairs_hook
argument), donc une conversion explicite des seuls dictionnaires qui doivent être ordonnés est également logique.la source
La commande de chargement normalement utilisée fonctionnera si vous spécifiez le paramètre object_pairs_hook :
la source