默认字典defaultdict是字典dict的一个子类,第一个参数为default_factory属性提供初始值,默认为None。它覆盖一个方法并添加一个可写的实例变量。其他功能和普通的dict相同,但是会为不存在的键提供默认值,从而避免KeyError异常。
1 单值映射字典中的使用
1.1 初始化时的情形
初始化之前先来看一看普通字典的情形
一般的dict会导致KeyError异常
count = {}
count['apple']
count['cherry']
print(count)
result:
Traceback (most recent call last):
File "D:/interview/interview/22.py", line 2, in <module>
count['apple']
KeyError: 'apple'
1.1.1 类型名称作为初始化时的参数
from collections import defaultdict
count = defaultdict(int)
count['apple']
count['cherry']
print(count)
result:
defaultdict(<class 'int'>, {'apple': 0, 'cherry': 0})
1.1.2 可调用函数作为初始化时的参数
def zero():
return 0
count = defaultdict(zero)
count['apple']
count['cherry']
print(count)
result:
defaultdict(<function zero at 0x0000020D4DE55048>, {'apple': 0, 'cherry': 0})
1.2 更新时的情形
继承字典的所有方法,默认字典在初始化时必须指定字典的默认值
from collections import defaultdict
dic = defaultdict(dict)
dic["k1"].update({"asdsa":"123"})
print(dic)
result:
defaultdict(<class 'dict'>, {'k1': {'asdsa': '123'}})
字典dic在定义的时候就已经定义了值为字典类型,所以即使字典中没有k1这个键,仍然可以执行字典的update方法。这种操作方式在普通的字典中会报错
2 多值映射字典的情形
一般而言,字典就是一个键对应一个单值的映射,如果想要一个键映射多个值,可以将多个值放到容器中。
2.1 初始化时的情形
2.1.1 普通字典的操作
dict1 = {
'a': [1, 2, 3],
'b': [4, 5]
}
dict2 = {
'a': {1, 2, 3},
'b': {4, 5}
}
至于具体使用列表还是集合取决于实际需要。如果想要保持元素的插入顺序那就使用列表,反之则使用集合即可。
2.1.2 使用默认字典的操作
from collections import defaultdict
dict1 = defaultdict(list)
dict1['a'].append(1)
dict1['a'].extend([2, 3])
dict1['b'].extend([4, 5])
dict2 = defaultdict(set)
dict2['a'].add(1)
dict2['a'].update([2, 3])
dict2['b'].update([4, 5])
print(f'dict1===={dict1}')
print(f'dict2===={dict2}')
result:
dict1====defaultdict(<class 'list'>, {'a': [1, 2, 3], 'b': [4, 5]})
dict2====defaultdict(<class 'set'>, {'a': {1, 2, 3}, 'b': {4, 5}})
使用defaultdict需要注意的一点,defaultdict会为不存在的键也创建映射实体(其实就是值)。如果你不需要这个特性,可以在普通字典上使用setdefault()方法进行替代
2.1.3 使用setdefault()方法进行替代defaultdict
dict1 = {}
dict1.setdefault('a', []).append(1)
dict1.setdefault('a', []).extend([2, 3])
dict1.setdefault('b', []).extend([4, 5])
print(f'dict1===={dict1}')
result:
dict1===={'a': [1, 2, 3], 'b': [4, 5]}
2.2 更新时的情形
2.2.1 普通字典的操作
一般来讲,创建一个多值映射字典是很简单的。但是选择自己实现的话则在进行值的初始化的时候会显得有点麻烦
d = {}
pairs = [('banana', 3), ('apple', 4), ('pear', 1), ('orange', 2), ('banana', 4), ('pear', -1),]
for key, value in pairs:
if key not in d:
d[key] = []
d[key].append(value)
print(d)
result:
{'banana': [3, 4], 'apple': [4], 'pear': [1, -1], 'orange': [2]}
2.2.2 默认字典的操作
from collections import defaultdict
d = defaultdict(list)
pairs = [('banana', 3), ('apple', 4), ('pear', 1), ('orange', 2), ('banana', 4), ('pear', -1),]
for key, value in pairs:
d[key].append(value)
print(d)
result:
defaultdict(<class 'list'>, {'banana': [3, 4], 'apple': [4], 'pear': [1, -1], 'orange': [2]})
可以看到,使用defaultdict会使得代码更加简洁