【Python进阶】可能是全网最详细的defaultdict讲解
1 什么是defaultdict
从名字上可以看出defaultdict
也是一个dict
,即键值对
。在讲什么是defaultdict
之前,我们先看看dict
的常规用法。
# 也可以写成dict = {} dic = dict() dic['a'] = 1 dic['b'] = 2 print(dic['a']) print(dic['b']) print(dic['c'])
输出结果如下:
1 2 Traceback (most recent call last): File "test.py", line 7, in <module> print(dic['c']) KeyError: 'c'
可以看到,如果dict
中没有对应的key
则会抛出KeyError
异常。针对这种情况,一般做法是调用dict
的get
方法,给一个默认值:
c = dic.get('c', 0)
今天我们要学习的defaultdict便是解决这种带有默认值的dict,上面示例可以用defaultdict来解决:
from collections import defaultdict dic = defaultdict(int) dic['a'] = 1 dic['b'] = 2 print(dic['a']) print(dic['b']) print(dic['c'])
输出如下:
1 2 0
2 常规用法
defaultdict
接受一个类型对象或函数对象,在取值时,如果不存在对应的key
则返回对应的函数返回值或默认构造函数的实例对象:
from collections import defaultdict dic_1 = defaultdict(int) dic_2 = defaultdict(tuple) dic_3 = defaultdict(list) dic_4 = defaultdict(str) dic_5 = defaultdict(set) print(dic_1['a']) print(dic_2['a']) print(dic_3['a']) print(dic_4['a']) print(dic_5['a'])
输出结果如下:
0 () [] set()
3 自定义默认类型
上面小节我们用了python
内置类型,接下来我们使用自定义类型:
from collections import defaultdict class Cls: def __init__(self, val='hello'): self.val = val def __str__(self): return self.val def fun(val=121): return val dic_1 = defaultdict(Cls) dic_2 = defaultdict(fun) print(dic_1['a']) print(dic_2['a'])
可以看到,如果传入的是类对象,那么默认值会调用类的构造函数并返回对应实例;如果是函数,则直接调用函数,并将函数返回值作为默认值。
4 重复调用生成默认值吗?
当我们多次取不存在的相同key对应的默认值时,会多次调用函数或构造函数吗?我们看一个示例:
from collections import defaultdict def fun(val=121): print('创建了默认值') return val dic = defaultdict(fun) for i in range(1000): dic['a'] print('------') dic['b']
输出结果如下:
创建了默认值 ------ 创建了默认值
可以看到,同一个key
只会调用了一次取默认值函数。
5 返回的默认值是同一个对象吗?
当key
相同时返回的默认值是同一个对象吗?当key
不同时返回的默认值是同一个对象吗?
from collections import defaultdict class Cls: def __init__(self, val='hello'): self.val = val def __str__(self): return self.val dic = defaultdict(Cls) print(dic['a']== dic['a']) print(dic['a']== dic['b'])
输出结果如下:
True False
从第4小节我们说过:同一个key只会调用了一次取默认值函数。 因此也能理解第一个返回结果是True。同理,不同的key会调用分开调用去默认值,因此第二个返回False