Dictionary mit beliebiger verschachtlungs Tiefe aufbauen

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
Spark
User
Beiträge: 7
Registriert: Dienstag 25. Juli 2006, 11:17

Hi
ich habe eine Datenstruktur die ich automatisiert in einem verschachtelten dictionary abbilden möchte:

Code: Alles auswählen

Root:
    Node1A:
        1,2,3
    Node1B:
        Node2A:
            56,45,456
   Node1C:
       'Description'
einen neuen Knoten, z.B. Node2A, würde ich mit folgendem Aufruf einfügen wobei das zweite Argument die Knotennamen enthält:

Code: Alles auswählen

MyDict = addNode(MyDict,['Root', 'Node1B'], 'Node2A')
Jetzt stellt sich die Frage, wie ich am einfachsten durch die verschatelten dictionaries navigiere und weitere anhängen kann.
Gehe ich von der richtigen Seite an das Problem heran? Bin dankbar für jede gute Idee!
Spark
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich würde eher Dicts so wrappen, dass ``addNode`` eine Methode des Parent Node ist, so wie etwa DOM das macht. Zum Navigieren würde ich etwa ``node_query`` schreiben, dem man die Namen der Nodes hinereinander angeben kann und es dann die Struktur herunternavigiert indem es die als Parameter angegebenen Keys in den Childnodes abläuft.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

class DeepDict(dict):
    def insert(self, roots, node, value=None):
        if not value: value = {} # damn mutable thing
        current = self
        for root in roots:
                current = current[root]
        try:
            current[node] = value
        except TypeError:
            raise TypeError("Not a node!")

    def query(self, *path):
        current = self
        for node in path:
            current = current[node]
        return current

if __name__ == '__main__':
    d = DeepDict()
    d.insert([], 'root')
    d.insert(['root'], 'node_1a', [1,2,3])
    try:
        d.insert(['root', 'node_1a'], 'node_1b', [2,2,2])
    except TypeError:
        pass
    d.insert(['root'], 'node_2a')
    d.insert(['root', 'node_2a'], 'node_2b', [4,3,2])
    print d.query('root', 'node_2a', 'node_2b')
    print d
Spark
User
Beiträge: 7
Registriert: Dienstag 25. Juli 2006, 11:17

Vielen Dank für die prompten Antworten! Der Sourcecode entspricht ganau dem wonach ich gesucht habe. Insbesondere gefällt mir die Datenkapselung.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo audax

Ich finde das obige Code-Beispiel sehr interessant. Musste mit Entsetzen feststellen, dass ich noch lange nicht alles über die Pythonprogrammierung weiss. Frage an dich, wäre es dir möglich die Klasse 'DeepDict' mit einer 'remove' Methode zu erweitern? Ich meine damit, dass irgend ein Node-Elemment aus der Baumstruktur entfernen kann.

Besten Dank für deine Bemühung.

Gruss wuf :wink:
Take it easy Mates!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

class DeepDict(dict):
    def insert(self, roots, node, value=None):
        if not value: value = {} # damn mutable thing
        current = self
        for root in roots:
                current = current[root]
        try:
            current[node] = value
        except TypeError:
            raise TypeError("Not a node!")

    def query(self, *path):
        current = self
        for node in path:
            current = current[node]
        return current

    def remove(self, *path):
        self.query(*path).clear()


if __name__ == '__main__':
    d = DeepDict()
    d.insert([], 'root')
    d.insert(['root'], 'node_1a', [1,2,3])
    try:
        d.insert(['root', 'node_1a'], 'node_1b', [2,2,2])
        raise Exception("No TypeError thrown!")
    except TypeError:
        pass
    d.insert(['root'], 'node_2a')
    d.insert(['root', 'node_2a'], 'node_2b', [4,3,2])
    print d.query('root', 'node_2a', 'node_2b')
    d.remove('root', 'node_2a')
    try:
        print d.query('root', 'node2_a')
        raise Exception("Got invalid key!")
    except KeyError:
        pass
    print d
Das hättest du aber mal kurz in die Doku von `dict` schauen können ;)
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo audax

Vielen Dank für deine Hilfe. Sorry, dass ich dir ein bisschen Zeit gestohlen habe. Hoffe, dass ich auch dir eines Tages einmal helfen kann. Vielleich bei einem undokummentierten Problem Hi.

Wünsche dir alles Gute und viel Erfolg.

Gruss wuf :wink:
Take it easy Mates!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Ach, is ja kein Problem...das hat mich ~2 Minuten gekostet ;)
[ 1 Minuten Doku schaun und 1 Minute Tippen :D ]
Antworten