verschachteltes Dictionary erweitern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
stevie004
User
Beiträge: 2
Registriert: Dienstag 10. September 2019, 14:56

Hallo,

ich bin relativ Neu in der Pythonprogrammierung und versuche gerade ein Dictionary um einen Eintrag zu erweitern aber ich komme nicht dahinter:
Also als erstes lese ich ein json File ein und versuche dann zu erweitern

Code: Alles auswählen

with open('file', 'r') as f:
    orig_dict = json.load(f)
    print (orig_dict)
    #{'nummer1': {'nummer2': {'nummer3': {'key1': 'Value A', 'key2': 'Value B'}}}}
   
So jetzt ist mein Versuch unter 'nummer3 etwas einzufügen also key3:Value. Ich hoffe es hat jemand einen Tipp für mich.

Endergebnis soll so aussehen: {'nummer1': {'nummer2': {'nummer3': {'key1': 'Value A', 'key2': 'Value B', 'key3' : 'Value C' }}}}

Alles was ich bis jetzt geschafft habe, ist das Dictionary so zu erweitern.....
{'nummer1': {'nummer2': {'nummer3': {'key1': 'Value A', 'key2': 'Value B'}}}}, 'key3': 'Value C'}

Ich habe natürlich die Suche bemüht und diesen Eintrag gefunden:
viewtopic.php?f=1&t=38844&p=297457&hili ... rn#p297457

Aber leider werde ich aus der Antwort nicht schlau..

Danke
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Wie greift man auf den Wert eines dicts zu?

Code: Alles auswählen

dictionary["key"]
Und wenn der Wert dort wieder ein dictionary ist, kann man dort einen Wert ebenso abrufen:

Code: Alles auswählen

orig_dict["nummer1"]["nummer2"]
.
Und wenn der Wert dort wieder ein dict ist...

Und da du weißt, wie man einen Wert in einem dict setzt, musst du das nur bei dem richtigen dict tun. Sollte die Funktion "update" irgendwo verwendet werden (wie in dem von dir verlinkten Thread) ist das zumindest ein ungewöhnlicher - wahrscheinlich ein falscher - Weg.
stevie004
User
Beiträge: 2
Registriert: Dienstag 10. September 2019, 14:56

Vielen Dank für die Erklärung,

ich konnte damit das Problem für mich lösen.

So einfach kanns gehen...
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@stevie004: Noch ein paar Anmerkungen zum Quelltext:

Beim öffnen von Textdateien sollte man immer explizit die Kodierung angeben. Die JSON-Spezifikation geht mehr oder weniger nur von ASCII aus, aber wenn eine andere Kodierung verwendet wird, ist das in der Regel immer UTF-8. Da ASCII eine Untermenge von UTF-8 ist, schaded es nicht grundsätzlich UTF-8 anzugeben.

In Namen sollte man weder Abkürzungen (`f`, `orig`) noch Grunddatentypen (`dict`) verwenden. Wenn man `file` meint, sollte man nicht `f` schreiben. Bei den Grunddatentypen hat man öfter als man denkt das Problem das man den Datentyp im Laufe der Programmentwicklung ändert, und dann hat man entweder falschen, irreführende Namen im Quelltext, oder muss die überall anpassen.

Mit `pprint.pprint()`, was insbesondere bei vielen/tief verschachtelten Grunddatentypen die Ausgabe etwas übersichtlicher macht:

Code: Alles auswählen

#!/usr/bin/env python3
import json
from pprint import pprint


def main():
    with open("test.json", "r", encoding="utf-8") as file:
        data = json.load(file)
        pprint(data)
        # {'nummer1': {'nummer2': {'nummer3': {'key1': 'Value A', 'key2': 'Value B'}}}}
        data["nummer1"]["nummer2"]["nummer3"]["key3"] = "Value C"
        pprint(data)
        # {'nummer1': {'nummer2': {'nummer3': {'key1': 'Value A',
        #                                      'key2': 'Value B',
        #                                      'key3': 'Value C'}}}}


if __name__ == "__main__":
    main()
Eine Alternative zu `pprint` ist das externe `prettyprinter`, das einen anderen Algorithmus für das Layout verwendet und am Terminal auch farbige Ausgaben machen kann. Wenn man das statt `pprint` so importiert: ``from prettyprinter import cpprint as pprint`` bekommt man diese Ausgabe:

Code: Alles auswählen

{
    'nummer1': {
        'nummer2': {'nummer3': {'key1': 'Value A', 'key2': 'Value B'}}
    }
}
{
    'nummer1': {
        'nummer2': {
            'nummer3': {
                'key1': 'Value A',
                'key2': 'Value B',
                'key3': 'Value C'
            }
        }
    }
}
Falls die Schlüssel in den Wörterbüchern gültige Bezeichner in Python sind, kann das externe `addict`-Modul den Zugriff per Attribute ermöglichen:

Code: Alles auswählen

#!/usr/bin/env python3
import json
from pprint import pprint

from addict import Dict


def main():
    with open("test.json", "r", encoding="utf-8") as file:
        data = Dict(json.load(file))
        pprint(data)
        data.nummer1.nummer2.nummer3.key3 = "Value C"
        pprint(data)


if __name__ == "__main__":
    main()
Für diesen Fall im Grunde mit Kanonen auf Spatzen geschossen wäre das (externe) `glom`-Modul:

Code: Alles auswählen

#!/usr/bin/env python3
import json
from pprint import pprint

from glom import assign


def main():
    with open("test.json", "r", encoding="utf-8") as file:
        data = json.load(file)
        pprint(data)
        assign(data, "nummer1.nummer2.nummer3.key3", "Value C")
        pprint(data)


if __name__ == "__main__":
    main()
Das Modul ist nützlich wenn man JSON-(ähnliche) Daten transformieren will. Also zum Beispiel Daten nach einem bestimmten Muster auswählen und/oder aggregieren. Das ist so ein bisschen wie XPATH/XSLT für XML.

Falls man JSON-Daten validieren und Werte konvertieren will und/oder aus Python-Objekten JSON nach einem bestimmten Schema erstellen möchte, sei noch auf das `marshmallow`-Modul hingewiesen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten