Aktualisiere den Wert eines verschachtelten Wörterbuchs mit unterschiedlicher Tiefe
Ich bin auf der Suche nach einem Weg, um update-dict-dictionary1 mit dem Inhalt der dict-update ohne überschreiben levelA
dictionary1={'level1':{'level2':{'levelA':0,'levelB':1}}}
update={'level1':{'level2':{'levelB':10}}}
dictionary1.update(update)
print dictionary1
{'level1': {'level2': {'levelB': 10}}}
Ich weiß, das update löscht die Werte in level2, weil es die Aktualisierung der niedrigste Schlüssel level1.
Wie könnte ich gegen dieses Problem, da dictionary1 und aktualisieren können beliebige Längen haben?
Kommentar zu dem Problem - Öffnen
Ist die Verschachtelung immer drei Ebenen tief oder kann man Schachtelung beliebiger Tiefe?
Es kann eine beliebige Tiefe/Länge.
InformationsquelleAutor der Frage jay_t | 2010-07-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
@FM-Antwort hat das Recht Allgemeine Idee, d.h. eine rekursive Lösung, aber etwas eigenartig Codierung und mindestens ein bug. Ich würde empfehlen, stattdessen:
Python 2:
Python 3:
Den Fehler zeigt sich, wenn die "update" hat eine
k
,v
Element, wov
ist eindict
undk
ist ursprünglich nicht ein Schlüssel im dictionary wird aktualisiert -- @FM ' s code "springt" dieser Teil des Updates (denn es führt ihn auf eine neue, leeredict
was nicht gespeichert oder zurückgegeben überall, nur verloren, wenn der rekursive Aufruf liefert).Meine anderen änderungen sind gering: es gibt keinen Grund für die
if
/else
konstruieren, wenn.get
macht die gleiche Arbeit schneller und sauberer, und dieisinstance
ist am besten angewendet, um abstrakte Basisklassen (nicht Beton) für die Allgemeinheit.InformationsquelleAutor der Antwort Alex Martelli
Nahm mir ein wenig auf diese ein, aber Dank @Alex ' s post, er füllte die Lücke, die mir fehlte. Stieß ich jedoch auf ein Problem, wenn ein Wert innerhalb des rekursiven
dict
passiert zu seinlist
, so dass ich dachte, ich würde teilen, und erweitern seine Antwort.InformationsquelleAutor der Antwort onosendi
@Alex ' s Antwort ist gut, aber funktioniert nicht beim ersetzen ein element wie eine Ganzzahl mit einem Wörterbuch, wie
update({'foo':0},{'foo':{'bar':1}})
. Dieses update behebt es:InformationsquelleAutor der Antwort bscan
Kleinere Verbesserungen zu @Alex ' s Antwort , ermöglicht die Aktualisierung der Wörterbücher von unterschiedlichen tiefen sowie die Begrenzung der Tiefe, dass das update taucht in der ursprünglichen verschachtelten dictionary (aber die Update-Wörterbuch der Tiefe ist nicht begrenzt). Nur in wenigen Fällen wurden getestet:
InformationsquelleAutor der Antwort hobs
Dieselbe Lösung wie das angenommen, aber klarer Benennung von Variablen, docstring, und es wurde ein Fehler behoben
{}
als würde der Wert nicht überschreiben.Hier sind ein paar test-Fälle:
Dieser Funktionen erhalten Sie in der Scharlatan Paket, in
charlatan.utils
.InformationsquelleAutor der Antwort charlax
Keiner dieser Antworten die Autoren scheinen zu verstehen, das Konzept der Aktualisierung eines Objekts in einem Wörterbuch gespeichert und auch der Iteration über dictionary-Elementen (im Gegensatz zu den Tasten). Also ich hatte zu schreiben, eine, die nicht sinnlos tautologisch Wörterbuch speichert und Abfragen.
Die dicts sind davon ausgegangen, dass die Speicherung von anderen dicts oder einfachen Typen.
Oder noch einfacher man arbeitet mit jeder Art:
InformationsquelleAutor der Antwort panda-34
Update zu @Alex Martelli Antwort fix ein Fehler in seinem Quelltext zu machen, die Lösung robuster:
Der Schlüssel ist, dass wir oft erstellen möchten gleichen Typ bei der Rekursion, also wir nutzen hier
v.copy().clear()
aber nicht{}
. Und dies ist besonders nützlich, wenn diedict
hier ist der Typcollections.defaultdict
die können unterschiedliche Arten vondefault_factory
s.Beachten Sie auch, dass die
u.iteritems()
wurde geändert, umu.items()
imPython3
.InformationsquelleAutor der Antwort thuzhf
Hier ist eine Unveränderliche version der rekursiven Wörterbuch Zusammenführen, falls jemand es braucht.
Basierend auf @Alex Martelli ist Antwort.
Python-2.x:
Python 3.x:
InformationsquelleAutor der Antwort kabirbaidhya
Benutzte ich die Lösung @Alex Martelli schlägt, aber es schlägt fehl,
TypeError 'bool' object does not support item assignment
wenn die beiden Wörterbücher unterscheiden sich im Datentyp auf einer Ebene.
Fall auf der gleichen Ebene, die element-Wörterbuch
d
ist nur ein Skalar (dh.Bool
), während das element Wörterbuchu
ist noch Wörterbuch die Neuzuweisung fehlschlägt, da kein dictionary-Zuordnung möglich ist, in scalar (wieTrue[k]
).Einer zusätzlichen Bedingung fixes:
InformationsquelleAutor der Antwort helvete
Könnte es sein, dass Sie stolpern über eine nicht-standard-Wörterbuch, so wie ich heute, die hat keine iteritems-Attribut.
In diesem Fall ist es leicht zu interpretieren, diese Art von Wörterbuch als standard-Wörterbuch. E. g.:
InformationsquelleAutor der Antwort noragen
Dass ein wenig an der Seite aber brauchen Sie wirklich verschachtelte dictionaries? Je nach problem, mal flacher Wörterbuch ausreichen kann... und gut Aussehen auf Sie:
InformationsquelleAutor der Antwort Nas Banov