it-swarm.com.de

Wie funktioniert collections.defaultdict?

Ich habe die Beispiele in den python -Dokumenten gelesen, kann aber immer noch nicht herausfinden, was diese Methode bedeutet. Kann jemand helfen? Hier sind zwei Beispiele aus den python -Dokumenten

>>> from collections import defaultdict

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]

und

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

die Parameter int und list sind wofür?

416
Lanston

In der Regel gibt ein Python Wörterbuch ein KeyError aus, wenn Sie versuchen, ein Element mit einem Schlüssel abzurufen, der sich derzeit nicht im Wörterbuch befindet. Im Gegensatz dazu werden mit defaultdict alle Elemente erstellt, auf die Sie zugreifen möchten (sofern sie noch nicht vorhanden sind). Um ein solches "Standard" -Element zu erstellen, ruft es das Funktionsobjekt auf, das Sie an den Konstruktor übergeben (genauer gesagt, es ist ein beliebiges "aufrufbares" Objekt, das Funktions- und Typobjekte enthält). Im ersten Beispiel werden Standardelemente mit int() erstellt, wodurch das Ganzzahlobjekt 0 zurückgegeben wird. Für das zweite Beispiel werden Standardelemente mit list() erstellt, wodurch ein neues leeres Listenobjekt zurückgegeben wird.

473
Sven Marnach

defaultdict bedeutet, dass, wenn kein Schlüssel im Wörterbuch gefunden wird, anstelle eines KeyError ein neuer Eintrag erstellt wird. Der Typ dieses neuen Eintrags ergibt sich aus dem Argument von defaultdict.

Zum Beispiel:

somedict = {}
print(somedict[3]) # KeyError

someddict = defaultdict(int)
print(someddict[3]) # print int(), thus 0
187
orlp

defaultdict

Das Standardwörterbuch enthält die Methode setdefault () zum Abrufen eines Werts und zum Einrichten eines Standardwerts, wenn der Wert nicht vorhanden ist. Im Gegensatz dazu lässt defaultdict den Aufrufer den Standardwert (den Wert, der zurückgegeben werden soll) vor dem Container angeben wird initialisiert. "

wie definiert von Doug Hellmann in Die Python Standardbibliothek am Beispiel

Wie benutzt man defaultdict?

Importiere defaultdict

>>> from collections import defaultdict

Initialisiere defaultdict

Initialisieren Sie es, indem Sie übergeben

aufrufbar als erstes Argument (obligatorisch)

>>> d_int = defaultdict(int)
>>> d_list = defaultdict(list)
>>> def foo():
...     return 'default value'
... 
>>> d_foo = defaultdict(foo)
>>> d_int
defaultdict(<type 'int'>, {})
>>> d_list
defaultdict(<type 'list'>, {})
>>> d_foo
defaultdict(<function foo at 0x7f34a0a69578>, {})

** kwargs als zweites Argument (optional)

>>> d_int = defaultdict(int, a=10, b=12, c=13)
>>> d_int
defaultdict(<type 'int'>, {'a': 10, 'c': 13, 'b': 12})

oder

>>> kwargs = {'a':10,'b':12,'c':13}
>>> d_int = defaultdict(int, **kwargs)
>>> d_int
defaultdict(<type 'int'>, {'a': 10, 'c': 13, 'b': 12})

Wie funktioniert es

Da es sich um eine untergeordnete Klasse des Standardwörterbuchs handelt, kann sie dieselben Funktionen ausführen.

Bei Übergabe eines unbekannten Schlüssels wird jedoch der Standardwert anstelle von error zurückgegeben. Zum Beispiel:

>>> d_int['a']
10
>>> d_int['d']
0
>>> d_int
defaultdict(<type 'int'>, {'a': 10, 'c': 13, 'b': 12, 'd': 0})

Wenn Sie den Standardwert ändern möchten, überschreiben Sie default_factory:

>>> d_int.default_factory = lambda: 1
>>> d_int['e']
1
>>> d_int
defaultdict(<function <lambda> at 0x7f34a0a91578>, {'a': 10, 'c': 13, 'b': 12, 'e': 1, 'd': 0})

oder

>>> def foo():
...     return 2
>>> d_int.default_factory = foo
>>> d_int['f']
2
>>> d_int
defaultdict(<function foo at 0x7f34a0a0a140>, {'a': 10, 'c': 13, 'b': 12, 'e': 1, 'd': 0, 'f': 2})

Beispiele in der Frage

Beispiel 1

Da int als default_factory übergeben wurde, gibt jeder unbekannte Schlüssel standardmäßig 0 zurück.

Jetzt, da die Zeichenfolge in der Schleife übergeben wird, wird die Anzahl dieser Alphabete in d erhöht.

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> d.default_factory
<type 'int'>
>>> for k in s:
...     d[k] += 1
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
>>> d
defaultdict(<type 'int'>, {'i': 4, 'p': 2, 's': 4, 'm': 1})

Beispiel 2

Da eine Liste als default_factory übergeben wurde, gibt jeder unbekannte (nicht vorhandene) Schlüssel standardmäßig [] (dh Liste) zurück.

Wenn die Liste der Tupel in der Schleife übergeben wird, wird der Wert in d [Farbe] angehängt.

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> d.default_factory
<type 'list'>
>>> for k, v in s:
...     d[k].append(v)
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
>>> d
defaultdict(<type 'list'>, {'blue': [2, 4], 'red': [1], 'yellow': [1, 3]})
79
Somendra Joshi

Hier finden Sie eine gute Erklärung für Standardwörter: http://ludovf.net/blog/python-collections-defaultdict/

Grundsätzlich sind die Parameter int und list Funktionen, die Sie übergeben. Denken Sie daran, dass Python Funktionsnamen als Argumente akzeptiert. int gibt standardmäßig 0 zurück und list gibt bei Aufruf mit eine leere Liste zurück Klammern.

Wenn ich in normalen Wörterbüchern in Ihrem Beispiel versuche, d[a] aufzurufen, erhalte ich eine Fehlermeldung (KeyError), da nur die Schlüssel m, s, i und p existieren und der Schlüssel a nicht initialisiert wurde. In einem defaultdict wird jedoch ein Funktionsname als Argument verwendet. Wenn Sie versuchen, einen nicht initialisierten Schlüssel zu verwenden, wird einfach die übergebene Funktion aufgerufen und der Rückgabewert als Wert des neuen Schlüssels zugewiesen.

18
varagrawal

Wörterbücher sind eine bequeme Möglichkeit, Daten zum späteren Abrufen nach Namen (Schlüssel) zu speichern. Schlüssel müssen eindeutige, unveränderliche Objekte sein und sind in der Regel Zeichenfolgen. Die Werte in einem Wörterbuch können beliebig sein. Bei vielen Anwendungen handelt es sich um einfache Typen wie Ganzzahlen und Zeichenfolgen.

Interessanter wird es, wenn die Werte in einem Wörterbuch Sammlungen (Listen, Dikte usw.) sind. In diesem Fall muss der Wert (eine leere Liste oder ein leeres Diktat) bei der ersten Verwendung eines bestimmten Schlüssels initialisiert werden. Dies ist zwar relativ einfach von Hand zu erledigen, aber der Standardtyp automatisiert und vereinfacht diese Art von Vorgängen. Ein Standarddiktat funktioniert genauso wie ein normales Diktat, wird jedoch mit einer Funktion („Standardfactory“) initialisiert, die keine Argumente akzeptiert und den Standardwert für einen nicht vorhandenen Schlüssel bereitstellt.

Ein defaultdict löst niemals einen KeyError aus. Jeder nicht vorhandene Schlüssel erhält den vom Standardwerk zurückgegebenen Wert.

from collections import defaultdict
ice_cream = defaultdict(lambda: 'Vanilla')

ice_cream['Sarah'] = 'Chunky Monkey'
ice_cream['Abdul'] = 'Butter Pecan'

print(ice_cream['Sarah'])
>>>Chunky Monkey

print(ice_cream['Joe'])
>>>Vanilla

Hier ist ein weiteres Beispiel zur Verwendung von defaultdict, mit dem wir die Komplexität reduzieren können

from collections import defaultdict
# Time complexity O(n^2)
def delete_nth_naive(array, n):
    ans = []
    for num in array:
        if ans.count(num) < n:
            ans.append(num)
    return ans

# Time Complexity O(n), using hash tables.
def delete_nth(array,n):
    result = []
    counts = defaultdict(int)

    for i in array:
        if counts[i] < n:
            result.append(i)
            counts[i] += 1
    return result


x = [1,2,3,1,2,1,2,3]
print(delete_nth(x, n=2))
print(delete_nth_naive(x, n=2))

Wenn Sie ein Wörterbuch benötigen und der Wert jedes Elements mit einem Standardwert beginnen soll, verwenden Sie abschließend ein defaultdict.

12
dimension

Meine eigenen 2 ¢: Sie können auch defaultdict in Unterklassen unterteilen:

class MyDict(defaultdict):
    def __missing__(self, key):
        value = [None, None]
        self[key] = value
        return value

Dies kann in sehr komplexen Fällen hilfreich sein.

6
Edward Falk

Da es um die Frage geht, wie es funktioniert, möchten manche Leser vielleicht mehr Schrauben und Muttern sehen. Insbesondere handelt es sich um die Methode __missing__(key). Siehe: https://docs.python.org/2/library/collections.html#defaultdict-objects .

Konkret zeigt diese Antwort, wie Sie __missing__(key) auf praktische Weise nutzen können: https://stackoverflow.com/a/17956989/1593924

Um zu verdeutlichen, was "aufrufbar" bedeutet, folgt eine interaktive Sitzung (ab 2.7.6, sollte aber auch in Version 3 funktionieren):

>>> x = int
>>> x
<type 'int'>
>>> y = int(5)
>>> y
5
>>> z = x(5)
>>> z
5

>>> from collections import defaultdict
>>> dd = defaultdict(int)
>>> dd
defaultdict(<type 'int'>, {})
>>> dd = defaultdict(x)
>>> dd
defaultdict(<type 'int'>, {})
>>> dd['a']
0
>>> dd
defaultdict(<type 'int'>, {'a': 0})

Das war die typischste Verwendung von defaultdict (mit Ausnahme der sinnlosen Verwendung der Variablen x). Sie können dasselbe mit 0 als explizitem Standardwert tun, jedoch nicht mit einem einfachen Wert:

>>> dd2 = defaultdict(0)

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    dd2 = defaultdict(0)
TypeError: first argument must be callable

Das Folgende funktioniert stattdessen, weil es eine einfache Funktion übergibt (es erstellt im laufenden Betrieb eine namenlose Funktion, die keine Argumente akzeptiert und immer 0 zurückgibt):

>>> dd2 = defaultdict(lambda: 0)
>>> dd2
defaultdict(<function <lambda> at 0x02C4C130>, {})
>>> dd2['a']
0
>>> dd2
defaultdict(<function <lambda> at 0x02C4C130>, {'a': 0})
>>> 

Und mit einem anderen Standardwert:

>>> dd3 = defaultdict(lambda: 1)
>>> dd3
defaultdict(<function <lambda> at 0x02C4C170>, {})
>>> dd3['a']
1
>>> dd3
defaultdict(<function <lambda> at 0x02C4C170>, {'a': 1})
>>> 
5
Jon Coombs

Ich denke, es wird am besten anstelle einer switch case-Anweisung verwendet. Stellen Sie sich vor, wir haben eine switch case-Anweisung wie folgt:

option = 1

switch(option) {
    case 1: print '1st option'
    case 2: print '2nd option'
    case 3: print '3rd option'
    default: return 'No such option'
}

In Python sind keine switch case-Anweisungen verfügbar. Wir können dasselbe erreichen, indem wir defaultdict verwenden.

from collections import defaultdict

def default_value(): return "Default Value"
dd = defaultdict(default_value)

dd[1] = '1st option'
dd[2] = '2nd option'
dd[3] = '3rd option'

print(dd[4])    
print(dd[5])    
print(dd[3])

Es druckt:

Default Value
Default Value
3rd option

Im obigen Snippet hat dd keine Tasten 4 oder 5 und gibt daher einen Standardwert aus, den wir in einer Hilfsfunktion konfiguriert haben. Dies ist viel schöner als ein unformatiertes Wörterbuch, in dem ein KeyError geworfen wird, wenn kein Schlüssel vorhanden ist. Daraus ist ersichtlich, dass defaultdict eher einer switch case-Anweisung ähnelt, bei der wir komplizierte if-Elif-elif-else -Blöcke vermeiden können.

Ein weiteres gutes Beispiel, das mich von diese Seite sehr beeindruckt hat, ist:

>>> from collections import defaultdict
>>> food_list = 'spam spam spam spam spam spam eggs spam'.split()
>>> food_count = defaultdict(int) # default value of int is 0
>>> for food in food_list:
...     food_count[food] += 1 # increment element's value by 1
...
defaultdict(<type 'int'>, {'eggs': 1, 'spam': 7})
>>>

Wenn wir versuchen, auf andere Elemente als eggs und spam zuzugreifen, erhalten wir eine Anzahl von 0.

2
Swadhikar C

Ohne defaultdict können Sie möglicherweise unsichtbaren Schlüsseln neue Werte zuweisen, diese aber nicht ändern. Zum Beispiel:

import collections
d = collections.defaultdict(int)
for i in range(10):
  d[i] += i
print(d)
# Output: defaultdict(<class 'int'>, {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9})

import collections
d = {}
for i in range(10):
  d[i] += i
print(d)
# Output: Traceback (most recent call last): File "python", line 4, in <module> KeyError: 0
2
Ming Liu

Nun, defaultdict kann im folgenden Fall auch einen Keyerror auslösen:

    from collections import defaultdict
    d = defaultdict()
    print(d[3]) #raises keyerror

Denken Sie immer daran, dem defaultdict Argumente wie defaultdict (int) zuzuweisen.

2
Shweta Sharma

Das defaultdict-Tool ist ein Container in der collection-Klasse von Python. Es ähnelt dem üblichen Dictionary-Container (Dict-Container), weist jedoch einen Unterschied auf: Der Datentyp der Wertfelder wird bei der Initialisierung angegeben.

Zum Beispiel:

from collections import defaultdict

d = defaultdict(list)

d['python'].append("awesome")

d['something-else'].append("not relevant")

d['python'].append("language")

for i in d.items():

    print i

Dies druckt:

('python', ['awesome', 'language'])
('something-else', ['not relevant'])
1
saarthak johari

Zusamenfassend:

defaultdict(int) - Das Argument int gibt an, dass die Werte vom Typ int sind.

defaultdict(list) - Die Argumentliste gibt an, dass die Werte vom Listentyp sind.

1
Shravan kp

Das Standardwörterbuch enthält die Methode setdefault () zum Abrufen eines Werts und zum Einrichten eines Standardwerts, wenn der Wert nicht vorhanden ist. Im Gegensatz dazu lässt defaultdict den Aufrufer den Standardwert vorab festlegen, wenn der Container initialisiert wird.

import collections

def default_factory():
    return 'default value'

d = collections.defaultdict(default_factory, foo='bar')
print 'd:', d
print 'foo =>', d['foo']
print 'bar =>', d['bar']

Dies funktioniert gut, solange alle Schlüssel den gleichen Standard haben. Dies kann besonders nützlich sein, wenn der Standardtyp zum Aggregieren oder Akkumulieren von Werten verwendet wird, z. B. eine Liste, eine Menge oder sogar ein Int. Die Standarddokumentation der Bibliothek enthält mehrere Beispiele für die Verwendung von defaultdict auf diese Weise.

$ python collections_defaultdict.py

d: defaultdict(<function default_factory at 0x100468c80>, {'foo': 'bar'})
foo => bar
bar => default value
0
user3818875