collections defaultdict(默认字典)

class collections.default([default_factory[, ...]]) 

返回一个类字典对象。defaultdict是内置类型dict的子类。他重写了父的一个方法并且增加了一个可以的实例变量。余下的功能与字典的一样,在这里就不写文档了。 
第一个参数为default_factory属性提供初始值;default_factory的默认值为None.余下的参数被视为dict构造器的参数包括关键字参数

defaultdict对象除了支持标准字典操作外,还支持下面的方法 
__missing__(key)

  • 如果default_factory属性为None,以key作为参数引发一个KeyError异常
  • 如果default_factory不是None,这个方法会被调用为key提供一个默认值,这个值会被赋值给key,并且返回
  • 当调用default_factory引发一个异常时,这个异常会被原封不动的传播
  • 当调用dict__getitme__()而需要的key没有被找到时,这个方法无论返回或引发什么都会被__getitem__()原封不动的返回
  • 注意这个__missing__()不会被任何操作调用除了__getitem()。这代表着get()方法,会像正常的字典方法一样,返回默认的None而不是调用default_factory

defaultdict对象提供下面的实例变量: 
这个属性用于__missing__()方法。他初始化由第一个参数,当作构造器,如果第一个参数存在,如果不存在,会是None

defaultdict 的例子

使用list作为default_factory,他很容易的将一个以键值形式表现的序列分组成一个字典列表

>>> 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])]

当每个key第一次被访问时,他们肯定没有在映射中:一个入口自动的被创建了使用default_factory函数返回一个空的列表。然后list.append()操作将值放入新的列表中。当key再次被访问时,查找工作正常(返回这个key的列表)然后list.append()操作为列表添加别外的值。这个技巧比等价的技艺(使用dict.setdefault())更简节,更快

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

default_factory设置成int使defaultdict对于计数非常有用

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
  • 当一个字每第一次被访问时,这个字母在映射中不存在,因此default_factory函数调用int()提供一个默认的0作为count。然后自增操作计算每个字母出现的次数 

int()函数总是返回0,因为他是常量函数的一个特殊的例子。一个更快更灵活的方式是创建一个常量函数(itertools.repeat() –可以提供任何常量,不仅仅是0)

>>> def constant_factory(value):
...     return itertools.repeat(value).next
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'
  • 设置default_factoryset使defaultdict构建集合字典非常有用
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> d.items()
[('blue', set([2, 4])), ('red', set([1, 3]))]

其实defaultdict 就是一个字典,只不过python自动的为它的键赋了一个初始值。这也就是说,你不显示的为字典的键赋初值python不会报错,看下实际例子。

比如你想计算频率

frequencies = {}
for word in wordlist:
    frequencies[word] += 1

python会抛出一个KeyError 异常,因为字典索引之前必须初始化,可以用下面的方法解决

for word in wordlist:
    try:
        frequencies[word] += 1
    except KeyError:
        frequencies[word] = 1
for word in wordlist:
    if word in frequencies:
        frequencies[word] += 1
    else:
        frequencies[word] = 1

当然,collections.defaultdict也可以轻松的解决这个问题

from collections import defaultdict
frequencies = defaultdict(int) #传入int()函数来初始化
for word in wordlist:
    frequencies[word] += 1

collections.defaultdict可以接受一个函数作为参数来初始化。什么意思呢,看上面的例子,我们想要frequencies[word]初始化为0,这时就可以用一个int()函数作为参数出给defaultdict,我们不带参数调用int(),int()就会返回一个0值













阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页