【python】collection库中defaultdict方法的使用

1、给空字典直接添加默认值会出bug

众所周知,在Python中如果访问字典中不存在的键,会引发KeyError异常。例如下面的例子:

strings = ('puppy', 'kitten', 'puppy', 'puppy',
           'weasel', 'puppy', 'kitten', 'puppy')
counts = {}
for kw in strings:
    counts[kw] += 1

该例子统计strings中某个单词出现的次数,并在counts字典中作记录。单词每出现一次,在counts相对应的键所存的值数字加1。但是事实上,运行这段代码会抛出KeyError异常,出现的时机是每个单词第一次统计的时候,因为Python的dict中不存在默认值的说法:

counts = dict()
counts
Out[13]: {}

counts['puppy'] += 1
Traceback (most recent call last):
  File "", line 1, in <module>
    counts['puppy'] += 1
KeyError: 'puppy'

使用判断语句检查。既然如此,首先可能想到的方法是在单词第一次统计的时候,在counts中相应的键存下默认值1。这需要在处理的时候添加一个判断语句:

strings = ('puppy', 'kitten', 'puppy', 'puppy',
           'weasel', 'puppy', 'kitten', 'puppy')
counts = {}

for kw in strings:
    if kw not in counts:
        counts[kw] = 1
    else:
        counts[kw] += 1

counts
Out[16]: {'kitten': 2, 'puppy': 5, 'weasel': 1}

2、使用dict.setdefault()方法来设置默认值

将counts[‘ooo’]赋予初始值

counts = {}
counts.setdefault('ooo',5)
Out[2]: 5

counts
Out[3]: {'ooo': 5}

统计不同的值的次数

strings = ('puppy', 'kitten', 'puppy', 'puppy',
           'weasel', 'puppy', 'kitten', 'puppy')
counts = {}

for kw in strings:
    counts.setdefault(kw, 0)
    counts[kw] += 1 

dict.setdefault()方法的返回值可以重写for循环中的代码,使其更加简洁:

strings = ('puppy', 'kitten', 'puppy', 'puppy',
           'weasel', 'puppy', 'kitten', 'puppy')
counts = {}

for kw in strings:
    counts[kw] = counts.setdefault(kw, 0) + 1

3、使用collections.defaultdict

defaultdict类就好像是一个dict,但是它是使用一个类型来初始化的:

from collections import defaultdict
dd = defaultdict(list)
dd

Out[19]: defaultdict(list, {})

defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值

dd['foo']
Out[25]: []
dd
Out[26]: defaultdict(list, {'foo': []})

dd['bar'].append('quux')
dd
Out[28]: defaultdict(list, {'bar': ['quux'], 'foo': []})

defaultdict类除了接受类型名称作为初始化函数的参数之外,还可以使用任何不带参数的可调用函数到时该函数的返回结果作为默认值,这样使得默认值的取值更加灵活。下面用一个例子来说明,如何用自定义的不带参数的函数zero()作为defaultdict类的初始化函数的参数:

from collections import defaultdict
def zero():
    return 0
dd = defaultdict(zero)
dd
Out[31]: defaultdict(, {})

dd['foo']
Out[32]: 0

如果是使用lambda匿名函数,lambda: 0 ,返回函数结果0值:

from collections import defaultdict

strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') 

counts = defaultdict(lambda: 0) # 使用lambda来定义简单的函数 

for s in strings: 
    counts[s] += 1

counts
Out[40]: 
defaultdict(lambda>>,
            {'kitten': 2, 'puppy': 5, 'weasel': 1})

你可能感兴趣的:(python)