Ich habe festgestellt, dass das json-Modul von Python (seit 2.6 enthalten) int-Wörterbuchschlüssel in Zeichenfolgen konvertiert, wenn Folgendes ausgeführt wird.
>>> import json
>>> releases = {1: "foo-v0.1"}
>>> json.dumps(releases)
'{"1": "foo-v0.1"}'
Gibt es eine einfache Möglichkeit, den Schlüssel als int beizubehalten, ohne die Zeichenfolge beim Speichern und Laden analysieren zu müssen? Ich glaube, es wäre möglich, die vom json-Modul bereitgestellten Hooks zu verwenden, aber auch dies erfordert noch eine Analyse. Gibt es möglicherweise ein Argument, das ich übersehen habe? Prost, chaz
Unterfrage: Danke für die Antworten. Gibt es eine einfache Möglichkeit, den Schlüsseltyp zu übermitteln, indem Sie möglicherweise die Ausgabe von Dumps analysieren, da json so funktioniert, wie ich befürchtet habe? Außerdem sollte ich beachten, dass der Code, der das Dumping ausführt, und der Code, der das JSON-Objekt von einem Server herunterlädt und lädt, beide von mir geschrieben wurden.
Antworten:
Dies ist einer dieser subtilen Unterschiede zwischen verschiedenen Mapping-Sammlungen, die Sie beißen können. JSON behandelt Schlüssel als Zeichenfolgen. Python unterstützt unterschiedliche Schlüssel, die sich nur im Typ unterscheiden.
In Python (und anscheinend in Lua) sind die Schlüssel für eine Zuordnung (Wörterbuch bzw. Tabelle) Objektreferenzen. In Python müssen sie unveränderliche Typen sein oder Objekte, die eine
__hash__
Methode implementieren . (Die Lua-Dokumente schlagen vor, dass die Objekt-ID automatisch als Hash / Schlüssel verwendet wird, auch für veränderbare Objekte, und dass die interne Zeichenfolge verwendet wird, um sicherzustellen, dass äquivalente Zeichenfolgen denselben Objekten zugeordnet werden.)In Perl, Javascript, awk und vielen anderen Sprachen sind die Schlüssel für Hashes, assoziative Arrays oder wie auch immer sie für die angegebene Sprache genannt werden, Zeichenfolgen (oder "Skalare" in Perl). In Perl
$foo{1}, $foo{1.0}, and $foo{"1"}
sind alle Verweise auf dasselbe Mapping in%foo
--- der Schlüssel wird als Skalar ausgewertet !JSON wurde als Javascript-Serialisierungstechnologie gestartet. (JSON steht für J ava S cript O bject N otation.) Natürlich implementiert es Semantik für seine Mapping-Notation, die mit seiner Mapping-Semantik übereinstimmt.
Wenn beide Enden Ihrer Serialisierung Python sein sollen, sollten Sie Pickles verwenden. Wenn Sie diese wirklich von JSON zurück in native Python-Objekte konvertieren müssen, haben Sie vermutlich mehrere Möglichkeiten. Zuerst könnten Sie versuchen (
try: ... except: ...
), einen beliebigen Schlüssel in eine Zahl umzuwandeln, falls die Suche nach einem Wörterbuch fehlschlägt. Wenn Sie dem anderen Ende (dem Serializer oder Generator dieser JSON-Daten) Code hinzufügen, können Sie alternativ eine JSON-Serialisierung für jeden der Schlüsselwerte durchführen lassen - und diese als Liste der Schlüssel bereitstellen. (Dann iteriert Ihr Python-Code zuerst über die Liste der Schlüssel, instanziiert / deserialisiert sie in native Python-Objekte ... und verwendet diese dann für den Zugriff auf die Werte aus der Zuordnung).quelle
Nein, in JavaScript gibt es keinen Zahlenschlüssel. Alle Objekteigenschaften werden in String konvertiert.
Dies kann zu merkwürdig wirkenden Verhaltensweisen führen:
JavaScript-Objekte sind keine wirklich richtigen Zuordnungen, wie Sie sie in Sprachen wie Python verstehen würden, und die Verwendung von Schlüsseln, die keine Zeichenfolgen sind, führt zu Verrücktheit. Aus diesem Grund schreibt JSON Schlüssel immer explizit als Zeichenfolgen, auch wenn dies nicht erforderlich erscheint.
quelle
999999999999999999999
konvertiert'999999999999999999999'
?Number
Typ ist ein IEEE 754-Doppel- Gleitkommawert: Sie erhalten 53 Bit Mantisse, sodass Sie bis zu 2⁵³ (9007199254740992) mit ganzzahliger Genauigkeit speichern können. Darüber hinaus werden ganze Zahlen auf andere Werte gerundet (daher 9007199254740993 === 9007199254740992). 999999999999999999999 rundet auf 1000000000000000000000, für die die StandarddarstellungtoString
lautet1e+21
.Alternativ können Sie auch versuchen, das Wörterbuch in eine Liste der Formate [(k1, v1), (k2, v2)] zu konvertieren, während Sie es mit json codieren, und es nach dem Zurückcodieren wieder in ein Wörterbuch konvertieren.
Ich glaube, dies erfordert etwas mehr Arbeit, wie eine Art Flag, um zu identifizieren, welche Parameter nach dem Zurückcodieren von json in ein Wörterbuch konvertiert werden sollen.quelle
Beantwortung Ihrer Unterfrage:
Dies kann durch Verwendung erreicht werden
json.loads(jsonDict, object_hook=jsonKeys2int)
Diese Funktion funktioniert auch für verschachtelte Diktate und verwendet ein Diktatverständnis.
Wenn Sie die Werte auch umwandeln möchten, verwenden Sie:
Dadurch wird die Instanz der Werte getestet und nur dann umgewandelt, wenn es sich um Zeichenfolgenobjekte handelt (um genau zu sein Unicode).
Beide Funktionen setzen voraus, dass Schlüssel (und Werte) Ganzzahlen sind.
Dank an:
Wie verwende ich if / else in einem Wörterbuchverständnis?
Konvertieren Sie einen Zeichenfolgenschlüssel in einem Wörterbuch in int
quelle
Ich bin von dem gleichen Problem gebissen worden. Wie bereits erwähnt, müssen die Zuordnungsschlüssel in JSON Zeichenfolgen sein. Sie können eines von zwei Dingen tun. Sie können eine weniger strenge JSON-Bibliothek wie demjson verwenden , die ganzzahlige Zeichenfolgen zulässt. Wenn keine anderen Programme (oder keine anderen in anderen Sprachen) es lesen werden, sollten Sie in Ordnung sein. Oder Sie können eine andere Serialisierungssprache verwenden. Ich würde keine Gurke vorschlagen. Es ist schwer zu lesen und nicht sicher . Stattdessen würde ich YAML vorschlagen, das (fast) eine Obermenge von JSON ist und ganzzahlige Schlüssel zulässt. (Zumindest PyYAML .)
quelle
Konvertieren Sie das Wörterbuch mithilfe
str(dict)
von: in einen String und konvertieren Sie es dann wieder in ein Diktat:quelle
Hier ist meine Lösung! Ich habe verwendet
object_hook
, es ist nützlich, wenn Sie verschachtelt habenjson
Es gibt nur einen Filter zum Parsen des JSON-Schlüssels auf int. Sie können den
int(v) if v.lstrip('-').isdigit() else v
Filter auch für den JSON-Wert verwenden.quelle
Ich habe eine sehr einfache Erweiterung von Murmels Antwort gemacht, von der ich denke, dass sie mit einem ziemlich willkürlichen Wörterbuch (einschließlich verschachtelter Wörterbücher) funktioniert, vorausgesetzt, es kann überhaupt von JSON ausgegeben werden. Alle Schlüssel, die als Ganzzahlen interpretiert werden können, werden in int umgewandelt. Zweifellos ist dies nicht sehr effizient, aber es funktioniert für meine Zwecke zum Speichern und Laden von JSON-Strings.
Angenommen, alle Schlüssel im ursprünglichen Diktat sind Ganzzahlen, wenn sie in int umgewandelt werden können, wird das ursprüngliche Wörterbuch nach dem Speichern als JSON zurückgegeben. z.B
quelle
Sie können Ihre
json.dumps
selbst schreiben , hier ist ein Beispiel von djson : encoder.py . Sie können es so verwenden:quelle