Dienstag, Februar 18, 2020

Bekomme ich die JSON-zum laden in eine OrderedDict?

Ok, so kann ich mit einem OrderedDict in json.dump. Das ist ein OrderedDict kann als input verwendet werden um JSON.

Aber es kann verwendet werden als eine Ausgabe? Wenn ja, wie? In meinem Fall möchte ich load in eine OrderedDict, so kann ich halten Sie die Reihenfolge der Schlüssel in die Datei.

Wenn nicht, gibt es dafür eine Art workaround?

Nie versucht, Ordnung zu erhalten, aber ich kann sicherlich sehen, wie es sinnvoll wäre.
Ja, in meinem Fall bin ich auf die überbrückung der Kluft zwischen verschiedenen Programmiersprachen und Anwendungen JSON funktioniert sehr gut. Aber die Reihenfolge der Tasten ist ein bisschen ein Problem. Genial wäre ein einfaches ankreuzen in json.load zu verwenden OrderedDicts statt Dicts in Python.
JSON-Spezifikation definiert den Objekt-Typ als ungeordnete Schlüssel… erwarten bestimmte Reihenfolge der Schlüssel ist ein Fehler
Key-die Bestellung ist in der Regel nicht für jede Art von funktionalen Anforderungen. Es ist vor allem eben auch für die menschliche Lesbarkeit. Wenn ich nur möchte, dass meine json-ziemlich-gedruckt, ich erwarte nicht, dass jeder das Dokument, um zu ändern.
Es hilft auch, zu vermeiden, große git-diffs!

InformationsquelleAutor c00kiemonster | 2011-08-03

6 Kommentare

  1. 554

    Ja, Sie können. Durch die Angabe der object_pairs_hook argument JSONDecoder. In der Tat, genau das Beispiel in der Dokumentation.

    >>> json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')
    OrderedDict([('foo', 1), ('bar', 2)])
    >>> 

    Können Sie diesen parameter übergeben, um json.loads (wenn Sie nicht brauchen, eine Decoder-Instanz für andere Zwecke) in etwa so:

    >>> import json
    >>> from collections import OrderedDict
    >>> data = json.loads('{"foo":1, "bar": 2}', object_pairs_hook=OrderedDict)
    >>> print json.dumps(data, indent=4)
    {
        "foo": 1,
        "bar": 2
    }
    >>> 

    Mit json.load erfolgt in der gleichen Weise:

    >>> data = json.load(open('config.json'), object_pairs_hook=OrderedDict)
    Ich bin ratlos. Die docs sagen, das object_pairs_hook aufgerufen wird, wird für jedes literal wird decodiert in Paare auf. Warum nicht erstellen Sie eine neue OrderedDict für jeden Datensatz im JSON?
    Hmm… die docs sind etwas zweideutig formuliert. Was Sie bedeuten, wie, dass die „gesamte Ergebnis der Dekodierung alle Paare“ verabschiedet werden, in der Reihenfolge, wie eine Liste, auf object_pairs_hook, anstatt „jedes paar wird übergeben werden object_pairs_hook,“
    Aber verliert die ursprüngliche Reihenfolge der Eingabe json?
    War überrascht zu sehen, dass json.load nicht halten es bestellt standardmäßig, aber wie es aussieht, ist nur spiegelung, was json selbst tut – die {} sind ungeordnet, aber die [] im json bestellt, wie beschrieben, hier

    InformationsquelleAutor SingleNegationElimination

  2. 124

    Einfache version für Python 2.7+

    my_ordered_dict = json.loads(json_str, object_pairs_hook=collections.OrderedDict)

    Oder für Python 2.4 2.6

    import simplejson as json
    import ordereddict
    
    my_ordered_dict = json.loads(json_str, object_pairs_hook=ordereddict.OrderedDict)
    python 2.6 kommt mit json.
    Ahhh, aber es hat nicht das die object_pairs_hook — welches ist, warum Sie immer noch müssen simplejson in 2.6. 😉
    Der Hinweis, dass simplejson und ordereddict sind in separaten Bibliotheken, die Sie benötigen, zu installieren.
    für python 2.7+: „import von json, Sammlungen“ im code, für python2.6- „aptitude install python-pip“ und „pip installieren ordereddict“ im system
    Das ist viel mehr easyier und schnell nach vorn als die bisherige Methode mit JSONDecoder.

    InformationsquelleAutor mjhm

  3. 26

    Einige tolle Neuigkeiten! Seit version 3.6 der cPython-Implementierung hat, erhalten die Einfügung Reihenfolge der Wörterbücher (https://mail.python.org/pipermail/python-dev/2016-September/146327.html). Dies bedeutet, dass die json-Bibliothek ist jetzt die Reihenfolge beibehalten standardmäßig aktiviert. 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 die resultierende Reihenfolge nicht definiert ist:

    {
        "fiddle": {
            "bar": 2,
            "foo": 1
        },
        "bar": 2,
        "foo": 1
    }

    In der cPython-Implementierung von python 3.6:

    {
        "foo": 1,
        "bar": 2,
        "fiddle": {
            "bar": 2,
            "foo": 1
        }
    }

    Die wirklich gute Nachricht ist, dass dies geworden eine Sprache, die die Spezifikation von python 3.7 (im Gegensatz zu einem Implementierungsdetail von cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283.html

    Also die Antwort auf deine Frage wird jetzt: die Aktualisierung auf python 3.6! 🙂

    Das ist eine gute Nachricht!
    Obwohl ich sehe das gleiche Verhalten, wie Sie in dem gegebenen Beispiel, in der CPython-Implementierung von Python 3.6.4, json.loads('{"2": 2, "1": 1}') wird {'1': 1, '2': 2} für mich.
    es sieht aus wie dict.__repr__ möglichen Tasten, während die zugrunde liegenden Bestellung erhalten. In anderen Worten, json.loads('{"2": 2, "1": 1}').items() ist dict_items([('2', 2), ('1', 1)]) auch wenn repr(json.loads('{"2": 2, "1": 1}')) ist "{'1': 1, '2': 2}".
    Hm, könnte sein; ich bin tatsächlich nicht in der Lage zu reproduzieren meiner eigenen Beobachtung in conda ist pkgs/main/win-64::python-3.6.4-h0c2934d_3, so wird das schwer zu testen.

    InformationsquelleAutor pelson

  4. 7

    Könnte man immer schreiben, aus der Liste der Schlüssel, die neben dumping das dict, und rekonstruieren Sie dann die OrderedDict durch Durchlaufen der Liste?

    +1 für low-tech-Lösung. Hab ich gemacht, dass beim Umgang mit das gleiche Problem mit YAML, aber mit zu duplizieren, ist irgendwie lahm, vor allem, wenn die zugrunde liegende format erhält die Bestellung. Könnte auch Sinn machen, um zu vermeiden, dass der Schlüssel-Wert-Paaren, die im dict, aber in der Liste fehlt der Schlüssel, und Heften Sie Sie auf nach all den ausdrücklich bestellten Artikel.
    Die low-tech-Lösung bewahrt auch der Kontext, ist ansonsten nicht unbedingt beibehalten im exportierten format (IOW; jemand sieht, JSON und es ist nichts da explizit „diese Schlüssel bleiben soll, in dieser Reihenfolge“, wenn Sie Manipulationen am it).
    Was bestimmt, dass die Liste der Schlüssel, die „gekippt“ sind in der richtigen Reihenfolge? Was ist mit verschachtelten dicts? Scheint, wie die dumping-würde behandeln müssen, und die Rekonstruktion sollte getan werden rekursiv mit OrdereDicts.

    InformationsquelleAutor Amber

  5. 5

    Neben dumping das geordnete Liste der Tasten neben dem Wörterbuch, ein weiterer low-tech-Lösung, die hat den Vorteil, dass Sie explizit ist, ist um einen dump der (geordnete) Liste von Schlüssel-Wert-Paare ordered_dict.items(); be ist eine einfache OrderedDict(<list of key-value pairs>). Diese Griffe eine geordnete Wörterbuch-trotz der Tatsache, dass JSON nicht über dieses Konzept (JSON-Wörterbücher haben keine Reihenfolge).

    Es ist in der Tat schön, wenn man sich die Tatsache zu nutze, dass json dumps die OrderedDict in der richtigen Reihenfolge. Allerdings ist es im Allgemeinen unnötig schwer und nicht unbedingt aussagekräftig sind, um Sie zu Lesen alle JSON-Wörterbücher als OrderedDict (durch die object_pairs_hook argument), also eine explizite Konvertierung von nur die Wörterbücher, die bestellt werden müssen, macht Sinn, auch.

    InformationsquelleAutor Eric O Lebigot

  6. 3

    Normalerweise verwendet load-Befehl funktionieren wird, wenn Sie angeben, die 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)

    InformationsquelleAutor ntg

Kostenlose Online-Tests