Kann ich JSON dazu bringen, in ein OrderedDict zu laden?
Lesezeit: 6 Minuten
c00kiemonster
Ok, also kann ich ein OrderedDict verwenden json.dump. Das heißt, ein OrderedDict kann als Eingabe für JSON verwendet werden.
Aber kann es als Ausgang verwendet werden? Wenn das so ist, wie? In meinem Fall würde ich gerne load in ein OrderedDict, damit ich die Reihenfolge der Schlüssel in der Datei beibehalten kann.
Wenn nicht, gibt es eine Art Workaround?
Ja, in meinem Fall überbrücke ich die Lücke zwischen verschiedenen Sprachen und Anwendungen, und JSON funktioniert sehr gut. Aber die Reihenfolge der Schlüssel ist ein bisschen ein Problem. Wäre toll, wenn es ein einfaches Häkchen geben würde json.load um OrderedDicts anstelle von Dicts in Python zu verwenden.
– c00kiemonster
3. August 2011 um 4:47 Uhr
Das ist ziemlich nervig. In Javascript (von dem json eine Teilmenge ist) wird die Reihenfolge der Schlüssel auch nicht beibehalten …
– SingleNegationElimination
3. August 2011 um 5:59 Uhr
Die JSON-Spezifikation definiert einen Objekttyp mit ungeordneten Schlüsseln … die Erwartung einer bestimmten Schlüsselreihenfolge ist ein Fehler
– Anentrop
10. Februar 2017 um 10:59 Uhr
Die Schlüsselreihenfolge ist normalerweise nicht für irgendeine Art von funktionalen Anforderungen. Es dient hauptsächlich nur der menschlichen Lesbarkeit. Wenn ich nur möchte, dass mein JSON hübsch gedruckt wird, erwarte ich nicht, dass sich irgendetwas an der Dokumentenreihenfolge ändert.
– Essiggurken
14. April 2017 um 22:56 Uhr
Es hilft auch, große Git-Diffs zu vermeiden!
– Richard Rast
12. Januar 2018 um 17:30 Uhr
SingleNegationElimination
Ja, du kannst. Durch die Angabe der object_pairs_hook Argument zu JSONDecoder. Tatsächlich ist dies genau das Beispiel, das in der Dokumentation angegeben ist.
>>> data = json.load(open('config.json'), object_pairs_hook=OrderedDict)
Ich bin ratlos. Die Dokumentation sagt, dass der object_pairs_hook für jedes Literal aufgerufen wird, das in Paare dekodiert wird. Warum wird dadurch nicht für jeden Datensatz im JSON ein neues OrderedDict erstellt?
– Tim Keating
25. April 2014 um 19:33 Uhr
Hmm … die Dokumente sind etwas mehrdeutig formuliert. Was sie damit meinen, dass das “Gesamtergebnis der Dekodierung aller Paare” der Reihe nach als Liste übergeben wird object_pairs_hookanstatt “jedes Paar wird an object_pairs_hook übergeben”,
– SingleNegationElimination
25. April 2014 um 20:25 Uhr
Aber verliert die ursprüngliche Reihenfolge des Eingabe-json?
– Islam
5. Oktober 2016 um 15:02 Uhr
Behält das Hinzufügen des OrderedDict-Hooks die Befehle im Diktat in einer tieferen Hierarchie?
– Zufällige Gewissheit
6. August 2019 um 14:50 Uhr
@RandomCertainty ja, jedes Mal, wenn beim Analysieren der Quelle auf ein JSON-Objekt gestoßen wird, OrderedDict wird verwendet, um den resultierenden Python-Wert aufzubauen.
import simplejson as json
import ordereddict
my_ordered_dict = json.loads(json_str, object_pairs_hook=ordereddict.OrderedDict)
Ahhh, aber es enthält nicht den object_pairs_hook – weshalb Sie immer noch simplejson in 2.6 benötigen. 😉
– mjhm
3. August 2011 um 9:05 Uhr
Möchte das anmerken simplejson und ordereddict sind separate Bibliotheken, die Sie installieren müssen.
– phunehehe
14. Dezember 2011 um 7:18 Uhr
für Python 2.7+: „import json, collections“ im Code, für python2.6- „aptitude install python-pip“ und „pip install ordereddict“ im System
– ZiTAL
30. Januar 2012 um 15:33 Uhr
Dies ist viel einfacher und schneller als die vorherige Methode mit JSONDecoder.
– Natim
19. September 2012 um 13:23 Uhr
Seltsamerweise wird der enthaltene Json in Pypy dies nicht tun loads('{}', object_pairs_hook=OrderedDict).
– Matthäus Schinckel
19. April 2013 um 10:59 Uhr
Tolle Neuigkeiten! Seit Version 3.6 hat die cPython-Implementierung die Einfügereihenfolge von Wörterbüchern beibehalten (https://mail.python.org/pipermail/python-dev/2016-September/146327.html). Dies bedeutet, dass die json-Bibliothek jetzt standardmäßig die Reihenfolge beibehält. Beachten Sie den Unterschied im Verhalten zwischen Python 3.5 und 3.6. Der Code:
import json
data = json.loads('{"foo":1, "bar":2, "fiddle":{"bar":2, "foo":1}}')
print(json.dumps(data, indent=4))
In py3.5 ist die resultierende Reihenfolge undefiniert:
Die Antwort auf Ihre Frage lautet also jetzt: Upgrade auf Python 3.6! 🙂
Obwohl ich im angegebenen Beispiel das gleiche Verhalten wie Sie sehe, in der CPython-Implementierung von Python 3.6.4, json.loads('{"2": 2, "1": 1}') wird {'1': 1, '2': 2} Für mich.
– Flüchtling
3. Juni 2018 um 18:55 Uhr
@fuglede so sieht es aus dict.__repr__ sortiert Schlüssel, während die zugrunde liegende Reihenfolge beibehalten wird. Mit anderen Worten, json.loads('{"2": 2, "1": 1}').items() ist dict_items([('2', 2), ('1', 1)]) selbst wenn repr(json.loads('{"2": 2, "1": 1}')) ist "{'1': 1, '2': 2}".
– Simon Charette
8. Februar 2019 um 23:00 Uhr
@SimonCharette Hm, könnte sein; Ich bin tatsächlich nicht in der Lage, meine eigene Beobachtung in Condas pkgs/main/win-64::python-3.6.4-h0c2934d_3 zu reproduzieren, daher wird dies schwer zu testen sein.
– Flüchtling
9. Februar 2019 um 8:48 Uhr
Dies hilft jedoch nicht wirklich weiter, da das “Umbenennen” von Schlüsseln immer noch die Reihenfolge der Schlüssel ruiniert.
– Hubro
30. Januar 2020 um 13:44 Uhr
Link zur Python-Dokumentation — In der Dokumentation wird erwähnt, dass “ab Python 3.7 das reguläre Diktat zur Beibehaltung der Reihenfolge wurde, sodass es nicht mehr erforderlich ist, es anzugeben collections.OrderedDict für die JSON-Generierung und -Analyse.”, was bedeutet, dass die Last standardmäßig in die eingefügt wird dict in der richtigen Reihenfolge.
– Benutzer202729
4. November 2020 um 13:58 Uhr
Sie könnten die Liste der Schlüssel immer zusätzlich zum Dumping des Diktats aufschreiben und dann rekonstruieren OrderedDict durch Iteration durch die Liste?
Eric O Lebigot
Zusätzlich zum Ausgeben der geordneten Liste von Schlüsseln neben dem Wörterbuch besteht eine weitere Low-Tech-Lösung, die den Vorteil hat, explizit zu sein, darin, die (geordnete) Liste von Schlüssel-Wert-Paaren auszugeben ordered_dict.items(); Das Laden ist einfach OrderedDict(<list of key-value pairs>). Dies behandelt ein geordnetes Wörterbuch, obwohl JSON dieses Konzept nicht hat (JSON-Wörterbücher haben keine Reihenfolge).
Es ist in der Tat schön, die Tatsache zu nutzen, dass json gibt das OrderedDict in der richtigen Reihenfolge aus. Es ist jedoch im Allgemeinen unnötig schwer und nicht unbedingt sinnvoll, es lesen zu müssen alle JSON-Wörterbücher als OrderedDict (über die object_pairs_hook Argument), also eine explizite Konvertierung von nur Sinnvoll sind auch die zu bestellenden Wörterbücher.
Der normalerweise verwendete Ladebefehl funktioniert, wenn Sie die angeben object_pairs_hook Parameter:
import json
from collections import OrderedDict
with open('foo.json', 'r') as fp:
metrics_types = json.load(fp, object_pairs_hook=OrderedDict)
11103800cookie-checkKann ich JSON dazu bringen, in ein OrderedDict zu laden?yes
Ja, in meinem Fall überbrücke ich die Lücke zwischen verschiedenen Sprachen und Anwendungen, und JSON funktioniert sehr gut. Aber die Reihenfolge der Schlüssel ist ein bisschen ein Problem. Wäre toll, wenn es ein einfaches Häkchen geben würde
json.load
um OrderedDicts anstelle von Dicts in Python zu verwenden.– c00kiemonster
3. August 2011 um 4:47 Uhr
Das ist ziemlich nervig. In Javascript (von dem json eine Teilmenge ist) wird die Reihenfolge der Schlüssel auch nicht beibehalten …
– SingleNegationElimination
3. August 2011 um 5:59 Uhr
Die JSON-Spezifikation definiert einen Objekttyp mit ungeordneten Schlüsseln … die Erwartung einer bestimmten Schlüsselreihenfolge ist ein Fehler
– Anentrop
10. Februar 2017 um 10:59 Uhr
Die Schlüsselreihenfolge ist normalerweise nicht für irgendeine Art von funktionalen Anforderungen. Es dient hauptsächlich nur der menschlichen Lesbarkeit. Wenn ich nur möchte, dass mein JSON hübsch gedruckt wird, erwarte ich nicht, dass sich irgendetwas an der Dokumentenreihenfolge ändert.
– Essiggurken
14. April 2017 um 22:56 Uhr
Es hilft auch, große Git-Diffs zu vermeiden!
– Richard Rast
12. Januar 2018 um 17:30 Uhr