Dank einiger großartiger Leute auf SO habe ich die Möglichkeiten entdeckt, die sich bieten collections.defaultdict
, insbesondere in Bezug auf Lesbarkeit und Geschwindigkeit. Ich habe sie mit Erfolg eingesetzt.
Jetzt möchte ich drei Ebenen von Wörterbüchern implementieren, die zwei obersten defaultdict
und die unterste int
. Ich finde keinen geeigneten Weg, dies zu tun. Hier ist mein Versuch:
from collections import defaultdict
d = defaultdict(defaultdict)
a = [("key1", {"a1":22, "a2":33}),
("key2", {"a1":32, "a2":55}),
("key3", {"a1":43, "a2":44})]
for i in a:
d[i[0]] = i[1]
Nun funktioniert dies, aber das Folgende, was das gewünschte Verhalten ist, funktioniert nicht:
d["key4"]["a1"] + 1
Ich vermute, ich hätte irgendwo erklären sollen, dass die zweite Ebene defaultdict
vom Typ ist int
, aber ich habe nicht gefunden, wo oder wie ich das tun soll.
Der Grund, den ich defaultdict
in erster Linie verwende, besteht darin, zu vermeiden, dass das Wörterbuch für jeden neuen Schlüssel initialisiert werden muss.
Noch eleganterer Vorschlag?
Danke Pythononeer!
quelle
multiprocessing
es unglücklich ist, diese hin und her zu senden.d[new_key]
Zugriff wird das Lambda aufgerufen, wodurch ein neues erstellt wirddefaultdict(int)
. Und wenn daraufd[existing_key][new_key2]
zugegriffen wird, wird eine neueint
erstellt.multiprocessing
und was ist eine benannte Funktion auf Modulebene? Diese Frage folgt.Eine andere Möglichkeit, ein auswählbares, verschachteltes Standarddikt zu erstellen, besteht darin, ein Teilobjekt anstelle eines Lambda zu verwenden:
Dies funktioniert, da auf die defaultdict-Klasse auf Modulebene global zugegriffen werden kann:
quelle
Schauen Sie sich hier die Antwort von nosklo an , um eine allgemeinere Lösung zu finden.
Testen:
Ausgabe:
quelle
Gemäß der Anfrage von @ rschwieb
D['key'] += 1
können wir die vorherige erweitern, indem wir die Addition durch Definieren der__add__
Methode überschreiben , damit sich diese eher wie eine verhältcollections.Counter()
Zuerst
__missing__
wird aufgerufen, um einen neuen leeren Wert zu erstellen, an den übergeben wird__add__
. Wir testen den Wert und zählen auf leere WerteFalse
.Weitere Informationen zum Überschreiben finden Sie unter Emulieren numerischer Typen .
Beispiele:
Anstatt zu überprüfen, ob das Argument eine Zahl ist (sehr nicht Python, Amirite!), Könnten wir einfach einen Standardwert von 0 angeben und dann die Operation versuchen:
quelle
Spät zur Party, aber für eine willkürliche Tiefe habe ich gerade so etwas gemacht:
Der Trick dabei besteht im Wesentlichen darin, die
DeepDict
Instanz selbst zu einer gültigen Factory zum Erstellen fehlender Werte zu machen. Jetzt können wir Dinge wie tunquelle
Wieder keine Fehler. Egal wie viele Ebenen verschachtelt sind. Pop auch kein Fehler
dd = DefaultDict ({"1": 333333})
quelle