【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 "<ipython-input-14-6a908838246f>", 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(<function __main__.zero>, {})

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(<function __main__.<lambda>>,
            {'kitten': 2, 'puppy': 5, 'weasel': 1})
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值