众所周知,在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}
将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
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})