Erstellen Sie Defaultdict von Defaultdict in Python

Olorunfemi Akinlua 21 Juni 2023
Erstellen Sie Defaultdict von Defaultdict in Python

Python hat eingebaute Container wie dict, list, set und tuple, die eine universelle Ideologie haben. Um diese Allzweck-Container zu erweitern oder zu verbessern, stellt Python ein Modul bereit, das spezialisierte Container-Datentypen namens Python Collections einführt.

Ein solcher spezialisierter Container-Datentyp ist defaultdict, der eine großartige Alternative (und eine Unterklasse) zu den standardmäßigen Python-Wörterbüchern (dict) darstellt. Mit defaultdict können Sie eine factory-Funktion bereitstellen, um fehlende Werte zu liefern (statt einer KeyError-Ausnahme oder -Meldung).

Wenn also der Schlüssel nicht im Wörterbuch vorhanden ist, wird die Funktion factory aufgerufen und gibt einen Wert zurück, anstatt eine KeyError-Ausnahme auszulösen.

Die Verwendung von defaultdict mag relativ einfach sein, aber die Arbeit mit defaultdict von defaultdict kann verwirrend sein. Dieser Artikel erklärt, wie man defaultdict von defaultdict erstellt, ohne Fehler zu verursachen, und wie die intrinsischen Operationen ablaufen.

Verwenden Sie lambda, um Defaultdict of Defaultdict in Python zu erstellen

Um Python-Sammlungen und von Natur aus defaultdict zu verwenden, können Sie das collection-Modul mit dem Python-Ausdruck importieren:

from collections import defaultdict

Beachten Sie, dass defaultdict eine Unterklasse der Klasse dict ist, die der folgende Python-Ausdruck überprüfen kann:

issubclass(defaultdict, dict)

Ausgang:

True

Wenn bei dict ein nicht vorhandener Schlüssel an das Wörterbuch übergeben wird, löst es die __missing__-Methode aus, die ein default_factory-Attribut enthält, das auf None gesetzt ist, und führt daher zu einer KeyError-Ausnahme. Wenn jedoch bei default_dict ein nicht vorhandener Schlüssel an das Wörterbuch übergeben wird, löst er das default_factory-Attribut der __missing__-Methode aus, das eine factory enthält, die einen Standardwert zurückgibt.

Zum Beispiel können wir ein defaultdict-Wörterbuch haben, das die factory-Funktion list enthält, die eine leere Liste zurückgibt, wenn ein nicht vorhandener Schlüssel übergeben wird.

from collections import defaultdict

ddict = defaultdict(list)
print(ddict["one"])

Ausgang:

[]

Obwohl ddict den Schlüssel one nicht hat, gibt es den Wert einer leeren Liste zurück, weil die Funktion factory übergeben wird. Es erstellt sogar den Schlüssel nach einem solchen Ausdruck.

from collections import defaultdict

ddict = defaultdict(list)
print(ddict["one"])
print(ddict["two"].append(1))

print(ddict)

Ausgang:

[]
defaultdict(<class 'list'>, {'one': [], 'two': [1]})

Nach den Anweisungen ddict["one"] und ddict["two"].append(1) erstellt es die jeweiligen Schlüssel und einen entsprechenden Wert basierend auf der Funktion list. Für die zweite Python-Anweisung erstellt es die leere Liste basierend auf der Attributfunktion default_factory und hängt ihr dann den Wert 1 an.

Die typische Gruppierung von Werten innerhalb eines defaultdict-Datentyps kann anders gehandhabt werden als bei einem dict-Datentyp.

sentence = "the man loves oranges, but also cares a great deal about apples"

letterStore = dict()

for i in sentence:
    if k not in letterStore:
        letterStore[i] = 1
        continue
    letterStore[i] += 1

print(letterStore.items())

Ausgang:

dict_items([('t', 4), ('h', 1), ('e', 7), (' ', 11), ('m', 1), ('a', 9), ('n', 2), ('l', 4), ('o', 4), ('v', 1), ('s', 5), ('r', 3), ('g', 2), (',', 1), ('b', 2), ('u', 2), ('c', 1), ('d', 1), ('p', 2)])

Die obige Gruppierung der Buchstaben kann stattdessen einfach mit der Verwendung von defaultdict durchgeführt werden. Anstatt den Codeblock, der prüft, ob die Buchstaben bereits im letterStore-Binding vorhanden sind, um eine Anfangsnummerierung zu erstellen, können wir defaultdict verwenden, um dies mit einer factory-Funktion zu erreichen – int.

from collections import defaultdict

sentence = "the man loves oranges, but also cares a great deal about apples"

letterStore = defaultdict(int)

for i in sentence:
    letterStore[i] += 1

print(letterStore.items())

Ausgang:

dict_items([('t', 4), ('h', 1), ('e', 7), (' ', 11), ('m', 1), ('a', 9), ('n', 2), ('l', 4), ('o', 4), ('v', 1), ('s', 5), ('r', 3), ('g', 2), (',', 1), ('b', 2), ('u', 2), ('c', 1), ('d', 1), ('p', 2)])

Damit wissen wir also, dass, wenn ein Schlüssel nicht existiert, die Methode __missing__ aufgerufen wird. Auch dessen Attribut default_factory wird getriggert, das eine Funktion enthält, die einen Wert zurückliefert.

Können wir jedoch ein defaultdict eines defaultdict erstellen? Ja, aber wie können wir das tun? Denn wenn Sie ein defaultdict an ein anderes defaultdict übergeben, führt dies zu einem Fehler.

from collections import defaultdict

d = defaultdict(defaultdict(int))
print(d)

Ausgang:

Traceback (most recent call last):
  File "c:\Users\USER\Desktop\JS\test.py", line 3, in <module>
    d = defaultdict(defaultdict(int))
TypeError: first argument must be callable or None

Ein TypeError wird ausgelöst, wenn wir den Code ausführen, und dies geschah wegen der Zeile d = defaultdict(defaultdict(int)), die besagt, dass das erste Argument muss aufrufbar oder None sein.

Mit diesen Informationen können wir ableiten, dass wir kein Callable (eine Funktion) oder None (Standardwert, den die default_factory enthält) übergeben haben, und das liegt daran, dass defaultdict(int) nicht aufrufbar ist. Es ist jedoch ein 'collections.defaultdict'.

Daher müssen wir einen Weg finden, ein Callable zu übergeben, bei dem lambda ins Spiel kommt.

lambda ermöglicht es uns, eine anonyme Funktion zu erstellen, die aufgerufen werden kann (ein Callable). So können wir für die obere Ebene defaultdict eine lambda-Funktion übergeben, die auf defaultdict(int) zeigt, die aufgerufen wird, wenn wir einen nicht vorhandenen Schlüssel übergeben.

Die Funktion lambda ruft die Funktion factory innerhalb des inneren defaultdict auf und gibt deren Wert zurück, der als Schlüsselwert gesetzt wird.

from collections import defaultdict

d = defaultdict(lambda: defaultdict(int))
print(d)

Ausgang:

defaultdict(<function <lambda> at 0x000001F6B9383E20>, {})

Um zu zeigen, dass es gut funktioniert, können wir auf die oberste Ebene defaultdict und die innere Ebene defaultdict zugreifen, indem wir die Quadratnotation verwenden, um ihre Standardwerte zu sehen, die an die Funktionen lambda bzw. int übergeben werden sollten .

print(d[0])
print(d[0][0])

Ausgang:

defaultdict(<class 'int'>, {})
0
Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn

Verwandter Artikel - Python Dictionary