collections.defaultdict如何运做?

我已经阅读了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])]

参数intlist是为了什么? shell


#1楼

这里有一个很好的解释: http//ludovf.net/blog/python-collections-defaultdict/ app

基本上,参数intlist是您传递的函数。 请记住,Python接受函数名做为参数。 int默认返回0,当使用括号调用时, list返回空列表。 函数

在正常的词典中,若是在你的例子中我尝试调用d[a] ,我将获得一个错误(KeyError),由于只有密钥m,s,i和p存在而密钥a还没有初始化。 可是在defaultdict中,它将函数名称做为参数,当您尝试使用还没有初始化的键时,它只调用您传入的函数并将其返回值指定为新键的值。 spa


#2楼

因为问题是“如何运做”,一些读者可能但愿看到更多的细节。 具体来讲,所讨论的方法是__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})
>>>

#3楼

标准字典包括用于检索值的方法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

#4楼

defaultdict

“标准字典包括用于检索值的方法setdefault(),若是该值不存在则创建默认值。相比之下, defaultdict容许调用者在初始化容器时预先指定默认值(要返回的值)。”

Doug HellmannPython标准库定义

如何使用defaultdict

导入defaultdict

>>> from collections import defaultdict

初始化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]})

#5楼

我本身的2¢:你也能够继承defaultdict:

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

对于很是复杂的案例,这可能会派上用场。

相关文章
相关标签/搜索