Gibt es eine Möglichkeit, eine zu haben defaultdict(defaultdict(int))
, damit der folgende Code funktioniert?
for x in stuff:
d[x.a][x.b] += x.c_int
d
muss ad-hoc erstellt werden, abhängig von x.a
und x.b
Elementen.
Ich könnte benutzen:
for x in stuff:
d[x.a,x.b] += x.c_int
aber dann könnte ich nicht verwenden:
d.keys()
d[x.a].keys()
python
collections
Jonathan
quelle
quelle
Antworten:
Ja genau so:
Das Argument von a
defaultdict
(in diesem Fall islambda: defaultdict(int)
) wird aufgerufen, wenn Sie versuchen, auf einen nicht vorhandenen Schlüssel zuzugreifen. Der Rückgabewert wird als neuer Wert dieses Schlüssels festgelegt, was in unserem Fall bedeutet, dass der Wert von seind[Key_doesnt_exist]
wirddefaultdict(int)
.Wenn Sie versuchen, von diesem letzten Standarddikt auf einen Schlüssel zuzugreifen
d[Key_doesnt_exist][Key_doesnt_exist]
, gibt er 0 zurück. Dies ist der Rückgabewert des Arguments des letzten Standarddikts, dint()
. H.quelle
defaultdict
(in diesem Fall istlambda : defaultdict(int)
) wird aufgerufen, wenn Sie versuchen, auf einen nicht vorhandenen Schlüssel zuzugreifen, und der Rückgabewert wird als neuer Wert dieses Schlüssels festgelegt, der in bedeutet unser Fall der Wertd[Key_dont_exist]
sein wirddefaultdict(int)
, und wenn Sie versuchen , einen Schlüssel aus diesem letzten defaultdict zugreifen dhd[Key_dont_exist][Key_dont_exist]
0 zurückgegeben wird , die der Rückgabewert des Arguments des letzten ist ,defaultdict
dhint()
, Hoffnung , das war hilfreich.defaultdict
sollte eine Funktion sein.defaultdict(int)
ist ein Wörterbuch, währendlambda: defaultdict(int)
eine Funktion ein Wörterbuch zurückgibt.defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
Der Parameter für den defaultdict-Konstruktor ist die Funktion, die zum Erstellen neuer Elemente aufgerufen wird. Verwenden wir also ein Lambda!
Seit Python 2.7 gibt es eine noch bessere Lösung mit Counter :
Einige Bonusfunktionen
Weitere Informationen finden Sie unter PyMOTW - Sammlungen - Containerdatentypen und Python-Dokumentation - Sammlungen
quelle
d = defaultdict(lambda : Counter())
eher verwenden alsd = defaultdict(lambda : defaultdict(int))
spezifisch ansprechen.d = defaultdict(Counter())
in diesem Fall einfach keine Notwendigkeit für ein Lambda verwendenCounter
Objekts übergeben. Das heißt:d = defaultdict(Counter)
Ich finde es etwas eleganter zu benutzen
partial
:Dies ist natürlich dasselbe wie ein Lambda.
quelle
Als Referenz ist es möglich, eine generische verschachtelte
defaultdict
Factory-Methode zu implementieren , indem Sie:Die Tiefe definiert die Anzahl der verschachtelten Wörterbücher, bevor der in definierte Typ
default_factory
verwendet wird. Zum Beispiel:quelle
ndd = nested_defaultdict(dict) .... ndd['a']['b']['c']['d'] = 'e'
WürfeKeyError: 'b'
depth=0
, was möglicherweise nicht immer erwünscht ist, wenn die Tiefe zum Zeitpunkt des Aufrufs unbekannt ist. Einfach durch Hinzufügen einer Zeileif not depth: return default_factory()
am oberen Rand der Funktion zu reparieren, obwohl es wahrscheinlich eine elegantere Lösung gibt.Frühere Antworten befassten sich mit der Erstellung von zwei oder n Ebenen
defaultdict
. In einigen Fällen möchten Sie eine unendliche:Verwendungszweck:
quelle
Andere haben Ihre Frage, wie Sie Folgendes zum Laufen bringen können, richtig beantwortet:
Eine Alternative wäre die Verwendung von Tupeln für Schlüssel:
Das Schöne an diesem Ansatz ist, dass er einfach ist und leicht erweitert werden kann. Wenn Sie eine dreistufige Zuordnung benötigen, verwenden Sie einfach ein Tupel mit drei Elementen für den Schlüssel.
quelle