在字典中查找某个值时,若key不存在时则会返回一个KeyError错误而不是一个默认值,这时候可以使用defaultdict函数。

注意:使用dict[key]=value时,若key不存在则报错;使用dict.get(key)时,若key不存在则会返回一个默认值。

defaultdict接受一个工厂函数作为参数,如下来构造:

dict =defaultdict( factory_function)

factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0。

defaultdict是python内建dict类的一个字类,功能与dict相同,但它带有一个默认的值,若key值不存在时返回一个默认的值。

测试一

from collections import defaultdict

dict1 = defaultdict(int)
dict2 = defaultdict(set)
dict3 = defaultdict(str)
dict4 = defaultdict(list)
dict4[1] = '666'
print(dict1[0])
print(dict2[0])
print(dict3[0])
print(dict4[0])
print(dict4[1])

输出:

0
set()

[]
666

测试二

from collections import defaultdict
def log_missing():
print('Key added')
return 0

current={'green' : 12, 'blue': 3}
increments = [
('red', 5), ('blue', 17), ('orange', 9),
]
result = defaultdict(log_missing, current)

print('Before: ', result, dict(result))
for key, amount in increments:
result[key] += amount
print('After: ', result, dict(result))

输出:

2022-08-09 06:59:10.687841: Hi there! 
2022-08-09 06:59:10.898213: Hi again!
Before: defaultdict(<function log_missing at 0x0000026AB9005488>, {'green': 12, 'blue': 3}) {'green': 12, 'blue': 3}
Key added
After: defaultdict(<function log_missing at 0x0000026AB9005488>, {'green': 12, 'blue': 3, 'red': 5}) {'green': 12, 'blue': 3, 'red': 5}
After: defaultdict(<function log_missing at 0x0000026AB9005488>, {'green': 12, 'blue': 20, 'red': 5}) {'green': 12, 'blue': 20, 'red': 5}
Key added
After: defaultdict(<function log_missing at 0x0000026AB9005488>, {'green': 12, 'blue': 20, 'red': 5, 'orange': 9}) {'green': 12, 'blue': 20, 'red': 5, 'orange': 9}

内嵌defaultdict的钩子函数

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
from collections import defaultdict


def increment_with_report(current, increments):
added_count = 0

def missing():
nonlocal added_count# Stateful closure
added_count += 1
return 0
result = defaultdict(missing, current)
for key, amount in increments:
result[key] += amount
return result, added_count


current = {'green': 12, 'blue': 3}
increments = [
('red', 5), ('blue', 17), ('orange', 9),
]

result, count = increment_with_report(current, increments)
assert count == 2
print(result, count)

输出:

2022-08-09 07:03:43.805543: Hi there! 
2022-08-09 07:03:44.022240: Hi again!
defaultdict(<function increment_with_report.<locals>.missing at 0x0000017272FC5510>, {'green': 12, 'blue': 20, 'red': 5, 'orange': 9}) 2