Gibt es eine Möglichkeit, ein Standarddikt auch zum Standard für das Standarddikt zu machen? (dh rekursives Standarddikt mit unendlicher Ebene?)
Ich möchte in der Lage sein:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Also kann ich tun x = defaultdict(defaultdict)
, aber das ist nur eine zweite Ebene:
x[0]
{}
x[0][0]
KeyError: 0
Es gibt Rezepte, die dies tun können. Aber kann es einfach mit den normalen defaultdict-Argumenten gemacht werden?
Beachten Sie, dass hier gefragt wird, wie ein rekursives Standarddikt auf unendlicher Ebene erstellt werden soll. Es unterscheidet sich also von Python: Standarddikt des Standarddikts? , wie man ein zweistufiges Standarddikt macht.
Ich werde wahrscheinlich nur das Bündelmuster verwenden , aber als mir klar wurde, dass ich nicht wusste, wie ich das machen soll, hat mich das interessiert.
quelle
Antworten:
Für eine beliebige Anzahl von Ebenen:
Natürlich kann man das auch mit einem Lambda machen, aber ich finde Lambdas weniger lesbar. Auf jeden Fall würde es so aussehen:
quelle
lambda
, funktioniert dies nicht.Die anderen Antworten hier zeigen Ihnen, wie Sie eine erstellen,
defaultdict
die "unendlich viele" enthältdefaultdict
, aber sie sprechen nicht das an, was meiner Meinung nach Ihr ursprüngliches Bedürfnis gewesen sein könnte, einfach ein Zwei-Tiefen-Standarddikt zu haben.Sie haben vielleicht gesucht:
Die Gründe, warum Sie dieses Konstrukt bevorzugen könnten, sind:
defaultdict
etwas anderes als ein Wörterbuch ist, z. B.:defaultdict(lambda: defaultdict(list))
Oderdefaultdict(lambda: defaultdict(set))
quelle
lambda
Formular ist korrekt - da dasdefaultdict(something)
ein wörterbuchähnliches Objekt zurückgibt, aberdefaultdict
ein aufrufbares Objekt erwartet! Danke dir!dict(result)
Dafür gibt es einen raffinierten Trick:
Dann können Sie Ihre
x
mit erstellenx = tree()
.quelle
Ähnlich wie die Lösung von BrenBarn, enthält jedoch nicht
tree
zweimal den Namen der Variablen , sodass sie auch nach Änderungen am Variablenwörterbuch funktioniert:Dann können Sie jedes neue
x
mit erstellenx = tree()
.Für die
def
Version können wir den Funktionsabschlussbereich verwenden, um die Datenstruktur vor dem Fehler zu schützen, bei dem vorhandene Instanzen nicht mehr funktionieren, wenn dertree
Name neu gebunden wird. Es sieht aus wie das:quelle
Ich würde auch eine Implementierung im OOP-Stil vorschlagen, die sowohl eine unendliche Verschachtelung als auch eine ordnungsgemäße Formatierung unterstützt
repr
.Verwendung:
quelle
*args
und**kwargs
das es zu funktionieren wie das erlaubtdefaultdict
, nämlich eine dict mit Schlüsselwort - Argumenten zu erstellen. Dies ist nützlich für die ÜbergabeNestedDefaultDict
anjson.load
Hier ist eine rekursive Funktion zum Konvertieren eines rekursiven Standarddiktats in ein normales Diktat
quelle
Ich habe diese Antwort von Andrew hier begründet. Wenn Sie Daten von einem JSON oder einem vorhandenen Diktat in das Standarddikt des Nesters laden möchten, sehen Sie sich dieses Beispiel an:
https://gist.github.com/nucklehead/2d29628bb49115f3c30e78c071207775
quelle