Python defaultdict使用可调用对象完全指南 | 高效字典处理
- Python
- 2025-07-22
- 584
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://www.521pj.cn/20256241.html
发表评论