我已经阅读了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
对于很是复杂的案例,这可能会派上用场。