在一个需求中意外的发现了defaultdict这个东西,python中的dict很好理解,可是有一个使用起来不方便的地方在于,需要进行初始值是否初始化的判断:
list = ["aaa", "bbb", "ccc", "aaa"]
kv = {}
for d in list:
if d in kv:
kv[d] += 1
else:
kv[d] = 1
print(kv)
# {"aaa": 2, "bbb": 1, "ccc": 1}
print(kv["test"])
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#KeyError: 'test'
对于python来说,这很不酷,所以,defaultdict这个东西就出现了,上面的代码,可以改为:
from collections import defaultdict
list = ["aaa", "bbb", "ccc", "aaa"]
kv = defaultdict(int)
for d in list:
kv[d] += 1
print(kv)
# {"aaa": 2, "bbb": 1, "ccc": 1}
print(kv["test"])
# 0
print(kv)
# {"aaa": 2, "bbb": 1, "ccc": 1, "test": 0}
也就是说,defaultdict能自动将没有创建的值,使用传入的函数来初始化,比如传入list,就能直接创建列表,使用的时候可以直接append。
除了这些基础用法,还有更加hack的用法,比如如下这个需求:
为对象进行编号,如果某几个属性相同,那么编为同一组。
这并不是一个多复杂的需求,只是用defaultdict来实现,会显得比其他方法优雅很多:
from collections import defaultdict
from itertools import count
group_value = defaultdict(count().__next__)
group_value_list = [group_value[(o.p1, o.p2, o.p3)] for o in object_list]
使用了count的next方法,在往group_value设置值的时候,会自动生成一个值,当key相同的时候,值是相同的,当key不同的时候,自动将数字增加1,当做值,这样,就能生成一个分组的列表了。
defaultdict增强了原dict的功能,并且如果创造力足够,会让程序更加优雅。
0 条评论