Python defaultdict使用可调用对象完全指南 | 高效字典处理
- Python
- 2025-07-22
- 375
Python defaultdict使用可调用对象
全面指南:高效处理字典中缺失键值的情况
defaultdict简介
defaultdict
是Python标准库collections
模块中的一个类,它继承自内置的dict
类。与普通字典不同,当尝试访问一个不存在的键时,defaultdict会自动创建该键并为其生成一个默认值。
基本语法
from collections import defaultdict # 创建一个defaultdict,指定默认值工厂函数 d = defaultdict(default_factory)
其中default_factory
是一个可调用对象(函数、lambda表达式、类等),当访问不存在的键时,defaultdict会调用这个函数来生成默认值。
可调用对象基础
在Python中,可调用对象是指任何可以通过函数调用操作符()
来调用的对象。主要包括:
- 内置函数:如
int
,list
,str
等 - 用户自定义函数:使用
def
关键字定义的函数 - Lambda表达式:匿名函数
- 类:调用类会创建该类的新实例
- 实现了__call__方法的对象
在defaultdict中,这个可调用对象应该是一个不需要参数的函数,或者所有参数都有默认值的函数。
内置函数作为工厂
Python的内置函数常被用作defaultdict的工厂函数,下面是一些常见用法:
示例1:使用int作为工厂
from collections import defaultdict # 使用int作为默认工厂,默认值为0 count_dict = defaultdict(int) words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'] for word in words: count_dict[word] += 1 print(count_dict) # 输出: defaultdict(<class 'int'>, {'apple': 3, 'banana': 2, 'orange': 1})
示例2:使用list作为工厂
from collections import defaultdict # 使用list作为默认工厂,默认值为空列表 group_dict = defaultdict(list) data = [('fruit', 'apple'), ('fruit', 'banana'), ('vegetable', 'carrot'), ('fruit', 'orange'), ('vegetable', 'potato')] for category, item in data: group_dict[category].append(item) print(group_dict) # 输出: defaultdict(<class 'list'>, { # 'fruit': ['apple', 'banana', 'orange'], # 'vegetable': ['carrot', 'potato'] # })
Lambda函数使用
当内置函数无法满足需求时,可以使用lambda表达式创建更复杂的默认值。
示例:使用Lambda表达式
from collections import defaultdict # 使用lambda设置默认值为一个字典 nested_dict = defaultdict(lambda: defaultdict(int)) data = [('A', 'X', 10), ('A', 'Y', 5), ('B', 'X', 7), ('A', 'X', 3)] for category, subcat, value in data: nested_dict[category][subcat] += value print(nested_dict['A']['X']) # 输出: 13 print(nested_dict['B']['Y']) # 输出: 0 (自动创建)
自定义函数示例
对于更复杂的场景,可以定义自己的函数作为工厂函数。
示例:自定义默认值函数
from collections import defaultdict import random def random_color(): """返回一个随机的RGB颜色元组""" return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) # 使用自定义函数作为默认工厂 color_dict = defaultdict(random_color) print(color_dict['background']) # 例如: (123, 45, 210) print(color_dict['text']) # 例如: (30, 180, 75) print(color_dict['background']) # 与第一次访问相同
类作为工厂
类也可以作为defaultdict的工厂函数,每次访问新键时会创建该类的一个新实例。
示例:使用类作为工厂
from collections import defaultdict class Person: def __init__(self, name=None): self.name = name self.attributes = {} def __repr__(self): return f"Person(name={self.name!r}, attributes={self.attributes})" # 使用Person类作为工厂 people_dict = defaultdict(Person) # 设置一些属性 people_dict['alice'].name = 'Alice' people_dict['alice'].attributes['age'] = 30 people_dict['bob'].name = 'Bob' people_dict['bob'].attributes['age'] = 25 print(people_dict['alice']) # 输出: Person(name='Alice', attributes={'age': 30}) # 访问不存在的键会创建一个新的Person实例 print(people_dict['charlie']) # 输出: Person(name=None, attributes={})
常见问题解答
Q: defaultdict与普通字典的setdefault方法有什么区别?
A: setdefault方法在键不存在时设置默认值并返回该值,而defaultdict在访问时自动创建默认值。defaultdict通常更高效,特别是需要多次设置默认值的场景。
Q: 工厂函数可以有参数吗?
A: defaultdict的工厂函数必须是不需要参数的函数。如果需要参数,可以包装在lambda中:defaultdict(lambda: your_function(arg))
。
Q: 如何改变已存在的defaultdict的默认工厂?
A: 可以通过设置default_factory
属性:d.default_factory = new_factory
。设置为None可恢复为普通字典行为(访问不存在的键会引发KeyError)。
动手练习
尝试修改下面的代码,观察defaultdict的行为:
代码编辑器
from collections import defaultdict def default_factory(): return "Default Value" d = defaultdict(default_factory) d['name'] = 'Alice' # 尝试访问存在的键 print("Key 'name':", d['name']) # 尝试访问不存在的键 print("Key 'age':", d['age'])
输出结果
Key 'name': Alice
Key 'age': Default Value
练习建议:
- 尝试将工厂函数改为
int
并访问数字键 - 尝试使用
lambda: 100
作为工厂函数 - 尝试嵌套 defaultdict 结构
© 2023 Python编程教程 | defaultdict使用指南
本教程仅用于学习目的,转载请注明出处
本文由JiLvHui于2025-07-22发表在吾爱品聚,如有疑问,请联系我们。
本文链接:https://521pj.cn/20256241.html
发表评论