Heim  >  Artikel  >  Backend-Entwicklung  >  Die Verwendung und der Unterschied zwischen Pythoncollections.defaultdict() und dict

Die Verwendung und der Unterschied zwischen Pythoncollections.defaultdict() und dict

高洛峰
高洛峰Original
2016-10-19 13:37:551761Durchsuche

In Python gibt es eine Modulsammlung, die als Datentyp-Containermodul erklärt wird. Es gibt eine Sammlung.defaultdict(), die häufig verwendet wird. Sprechen Sie hauptsächlich über diese Sache.

Übersicht:

Das defaultdict(function_factory) erstellt hier ein wörterbuchähnliches Objekt, in dem die Werte der Schlüssel selbst bestimmt werden, aber die Art der Werte ​ist eine Klasseninstanz von function_factory und hat einen Standardwert. Beispielsweise erstellt default(int) ein wörterbuchähnliches Objekt, in dem alle Werte Instanzen von int sind, und selbst wenn es sich um einen nicht vorhandenen Schlüssel handelt, hat d[key] auch einen Standardwert der Standardwert von int().

defaultdict

dict-Unterklasse, die eine Factory-Funktion aufruft, um fehlende Werte bereitzustellen.

Dies ist eine kurze Erklärung

defaultdict gehört zu einer Unterklasse der integrierten Funktion dict und ruft die Factory-Funktion auf, um den fehlenden Wert bereitzustellen.

Verwirrt, was ist eine Factory-Funktion:

Erklärung aus der Python-Kernprogrammierung

Python 2.2 vereinheitlicht Typen und Klassen, und alle integrierten Typen sind jetzt Klassen. Daraufhin Basierend darauf sind die ursprünglichen

sogenannten integrierten Konvertierungsfunktionen wie int(), type(), list() usw. mittlerweile zu Factory-Funktionen geworden. Das heißt, obwohl sie

ein bisschen wie Funktionen aussehen, handelt es sich tatsächlich um Klassen. Wenn Sie sie aufrufen, wird tatsächlich eine Instanz des Typs generiert, genau wie eine Fabrik, die Waren produziert.

Die folgenden bekannten Factory-Funktionen werden in älteren Python-Versionen als integrierte Funktionen bezeichnet:

int(), long(), float(), complex()

str (), unicode(), basestring()

list(), tuple()

type()

Andere Typen, die vorher keine Factory-Funktionen hatten, jetzt da sind ebenfalls Werksfunktionen. Darüber hinaus wurden auch entsprechende Factory-Funktionen für neue Datentypen hinzugefügt, die die neuen Stilklassen

unterstützen. Diese Factory-Funktionen sind unten aufgeführt:

dict()

bool()

set(), Frozenset()

object()

classmethod()

staticmethod()

super()

property()

file()

noch einmal Nehmen Ein Blick auf die Verwendung:

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

Es zeigt sich, dass defaultdict eine integrierte Funktionsliste als Parameter akzeptieren kann . Tatsächlich ist list() selbst eine integrierte Funktion, aber nach dem Update ist alles in Python ein Objekt, sodass list in eine Klasse umgewandelt wird und eine Instanz der Klasse generiert wird, wenn list eingeführt wird.

Ich verstehe immer noch nicht, schauen wir uns noch einmal die Hilfeerklärung von defaultdict an

classcollections.defaultdict([default_factory[, ...]])

Gibt a zurück neues wörterbuchähnliches Objekt. defaultdict ist eine Unterklasse der integrierten dict-Klasse und fügt eine beschreibbare Instanzvariable hinzu. Die verbleibende Funktionalität ist die gleiche wie für die dict-Klasse und wird hier nicht dokumentiert 🎜>Zuallererst: Ja,collections.defaultdict gibt ein wörterbuchähnliches Objekt zurück, nicht genau dasselbe Objekt. Die defaultdict-Klasse ist fast identisch mit der dict-Klasse, außer dass sie eine Methode überlädt und eine beschreibbare Instanzvariable hinzufügt. (beschreibbare Instanzvariablen, ich verstehe sie immer noch nicht)

Das erste Argument stellt den Anfangswert für das Attribut „default_factory“ bereit; der Standardwert ist „Keine“. Alle übrigen Argumente werden genauso behandelt, als ob sie an übergeben würden dict-Konstruktor, einschließlich Schlüsselwortargumenten.

Defaultdict-Objekte unterstützen zusätzlich zu den Standard-Dict-Operationen die folgende Methode:

__missing__(key)

Wenn das Attribut default_factory None ist, Dies löst eine KeyError-Ausnahme mit dem Schlüssel als Argument aus.

Wenn default_factory nicht None ist, wird es ohne Argumente aufgerufen, um einen Standardwert für den angegebenen Schlüssel bereitzustellen, dieser Wert wird in das Wörterbuch für den Schlüssel eingefügt und zurückgegeben .

Konzentrieren Sie sich hauptsächlich darauf. Wenn default_factory nicht None ist, wird diese default_factory in einer parameterlosen Form aufgerufen und stellt einen Standardwert für den Schlüssel der Methode ___missing__ bereit. Dieser Standardwert wird als Schlüssel in das Datenwörterbuch eingefügt und dann zurückgegeben.

Sehr schwindelig. Es gibt eine __missing__-Methode. Diese __missing__-Methode ist die integrierte Methode voncollections.defaultdict().

Wenn der Aufruf von „default_factory“ eine Ausnahme auslöst, wird diese Ausnahme unverändert weitergegeben.

Diese Methode wird von der __getitem__()-Methode der dict-Klasse aufgerufen, wenn der angeforderte Schlüssel nicht gefunden wird, was auch immer sie zurückgibt raises wird dann von __getitem__() zurückgegeben oder ausgelöst.

Beachten Sie, dass __missing__() für keine anderen Operationen als __getitem__() aufgerufen wird. Dies bedeutet, dass get() wie normale Wörterbücher standardmäßig None zurückgibt Anstatt default_factory zu verwenden.

defaultdict-Objekte unterstützen die folgende Instanzvariable:

default_factory

Dieses Attribut wird von der Methode __missing__() verwendet und ab dem ersten Argument initialisiert an den Konstruktor, falls vorhanden, oder an None, falls nicht vorhanden.

Es scheint, dass dieses Dokument schwer zu verstehen ist. Schauen Sie sich direkt das Beispiel an:

import collections
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
# defaultdict
d = collections.defaultdict(list)
for k, v in s:
    d[k].append(v)
# Use dict and setdefault   
g = {}
for k, v in s:
    g.setdefault(k, []).append(v)
      
# Use dict
e = {}
for k, v in s:
    e[k] = v
##list(d.items())
##list(g.items())
##list(e.items())

Schauen Sie sich das Ergebnis an


list(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
>>> list(g.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
>>> list(e.items())
[('blue', 4), ('red', 1), ('yellow', 3)]
>>> d
defaultdict(<class &#39;list&#39;>, {&#39;blue&#39;: [2, 4], &#39;red&#39;: [1], &#39;yellow&#39;: [1, 3]})
>>> g
{&#39;blue&#39;: [2, 4], &#39;red&#39;: [1], &#39;yellow&#39;: [1, 3]}
>>> e
{&#39;blue&#39;: 4, &#39;red&#39;: 1, &#39;yellow&#39;: 3}
>>> d.items()
dict_items([(&#39;blue&#39;, [2, 4]), (&#39;red&#39;, [1]), (&#39;yellow&#39;, [1, 3])])
>>> d["blue"]
[2, 4]
>>> d.keys()
dict_keys([&#39;blue&#39;, &#39;red&#39;, &#39;yellow&#39;])
>>> d.default_factory
<class &#39;list&#39;>
>>> d.values()
dict_values([[2, 4], [1], [1, 3]])

Es ist ersichtlich, dass der Effekt der Verwendung voncollections.defaultdict(list) dem der Verwendung von dict.setdefault() ähnelt

python help上也这么说了

When each key is encountered for the first time, it is not already in the mapping; so an entry is automatically created using the default_factory function which returns an empty list. The list.append() operation then attaches the value to the new list. When keys are encountered again, the look-up proceeds normally (returning the list for that key) and the list.append() operation adds another value to the list. This technique is simpler and faster than an equivalent technique using dict.setdefault():


说这种方法会和dict.setdefault()等价,但是要更快。

有必要看看dict.setdefault()

setdefault(key[, default])

If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.

如果这个key已经在dictionary里面存着,返回value.如果key不存在,插入key和一个default value,返回Default. 默认的defaults是None.


但是这里要注意的是defaultdict是和dict.setdefault等价,和下面那个直接赋值是有区别的。从结果里面就可以看到,直接赋值会覆盖。


从最后的d.values还有d[“blue”]来看,后面的使用其实是和dict的用法一样的,唯一不同的就是初始化的问题。defaultdict可以利用工厂函数,给初始keyi带来一个默认值。

这个默认值也许是空的list[]  defaultdict(list), 也许是0, defaultdict(int).


再看看下面的这个例子。

defaultdict(int) 这里的d其实是生成了一个默认为0的带key的数据字典。你可以想象成 d[key] = int default (int工厂函数的默认值为0)


d[k]所以可以直接读取 d[“m”] += 1 就是d[“m”] 就是默认值 0+1 = 1

后面的道理就一样了。

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


   


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn