我已經閱讀了python文檔中的示例,但仍然沒法弄清楚這個方法的含義。 有人能夠幫忙嗎? 如下是python文檔中的兩個示例 html
>>> 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)]
和 python
>>> 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])]
參數int
和list
是爲了什麼? shell
這裏有一個很好的解釋: http : //ludovf.net/blog/python-collections-defaultdict/ app
基本上,參數int和list是您傳遞的函數。 請記住,Python接受函數名做爲參數。 int默認返回0,當使用括號調用時, list返回空列表。 函數
在正常的詞典中,若是在你的例子中我嘗試調用d[a]
,我將獲得一個錯誤(KeyError),由於只有密鑰m,s,i和p存在而密鑰a還沒有初始化。 可是在defaultdict中,它將函數名稱做爲參數,當您嘗試使用還沒有初始化的鍵時,它只調用您傳入的函數並將其返回值指定爲新鍵的值。 spa
因爲問題是「如何運做」,一些讀者可能但願看到更多的細節。 具體來講,所討論的方法是__missing__(key)
方法。 請參閱: https : //docs.python.org/2/library/collections.html#defaultdict-objects 。 .net
更具體地說,這個答案顯示瞭如何以實用的方式使用__missing__(key)
: https : __missing__(key)
code
爲了澄清「可調用」的含義,這裏是一個交互式會話(從2.7.6開始,但也應該在v3中工做): htm
>>> 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})
這是defaultdict的最典型用法(除了毫無心義地使用x變量)。 您可使用0做爲顯式默認值執行相同的操做,但不能使用簡單值: blog
>>> dd2 = defaultdict(0) Traceback (most recent call last): File "<pyshell#7>", line 1, in <module> dd2 = defaultdict(0) TypeError: first argument must be callable
相反,如下工做是由於它傳入一個簡單的函數(它在運行中建立一個無名函數,它不帶參數而且老是返回0):
>>> dd2 = defaultdict(lambda: 0) >>> dd2 defaultdict(<function <lambda> at 0x02C4C130>, {}) >>> dd2['a'] 0 >>> dd2 defaultdict(<function <lambda> at 0x02C4C130>, {'a': 0}) >>>
並使用不一樣的默認值:
>>> dd3 = defaultdict(lambda: 1) >>> dd3 defaultdict(<function <lambda> at 0x02C4C170>, {}) >>> dd3['a'] 1 >>> dd3 defaultdict(<function <lambda> at 0x02C4C170>, {'a': 1}) >>>
標準字典包括用於檢索值的方法setdefault(),若是該值不存在則創建默認值。 相比之下,defaultdict容許調用者在初始化容器時指定默認的默認值。
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']
只要適合全部鍵具備相同的默認值,這種方法就能夠正常工做。 若是默認值是用於聚合或累積值的類型(例如list,set或甚至int),則它尤爲有用。 標準庫文檔包含幾個以這種方式使用defaultdict的示例。
$ python collections_defaultdict.py d: defaultdict(<function default_factory at 0x100468c80>, {'foo': 'bar'}) foo => bar bar => default value
「標準字典包括用於檢索值的方法setdefault(),若是該值不存在則創建默認值。相比之下, defaultdict
容許調用者在初始化容器時預先指定默認值(要返回的值)。」
由Doug Hellmann在Python標準庫中的定義
>>> from collections import defaultdict
經過傳遞初始化它
可調用做爲其第一個參數(必需)
>>> 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做爲其第二個參數(可選)
>>> d_int = defaultdict(int, a=10, b=12, c=13) >>> d_int defaultdict(<type 'int'>, {'a': 10, 'c': 13, 'b': 12})
要麼
>>> kwargs = {'a':10,'b':12,'c':13} >>> d_int = defaultdict(int, **kwargs) >>> d_int defaultdict(<type 'int'>, {'a': 10, 'c': 13, 'b': 12})
做爲標準字典的子類,它能夠執行全部相同的功能。
可是在傳遞未知密鑰的狀況下,它返回默認值而不是錯誤。 例如:
>>> d_int['a'] 10 >>> d_int['d'] 0 >>> d_int defaultdict(<type 'int'>, {'a': 10, 'c': 13, 'b': 12, 'd': 0})
若是您想更改默認值overwrite 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})
要麼
>>> 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})
例1
因爲int已做爲default_factory傳遞,所以默認狀況下任何未知鍵都將返回0。
如今,當字符串在循環中傳遞時,它將增長d中這些字母的數量。
>>> 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})
例2
因爲列表已做爲default_factory傳遞,所以任何未知(不存在)鍵將默認返回[](即列表)。
如今,當循環中傳遞元組列表時,它會將值附加到d [color]中
>>> 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]})
我本身的2¢:你也能夠繼承defaultdict:
class MyDict(defaultdict): def __missing__(self, key): value = [None, None] self[key] = value return value
對於很是複雜的案例,這可能會派上用場。