defaultdict是Python标准库collections模块提供的一种字典类型,是内置dict类的子类。与普通字典不同,它在访问不存在的键时不会抛出KeyError异常,而是调用预先指定的工厂函数生成一个默认值,并把该键值对写入字典。这一特性使分组、计数、累加等常见操作可以用更少的代码完成,因此在统计与数据归集场景中被广泛使用。
定义
defaultdict是Python的collections模块中定义的一种字典类型,是内置dict类的子类。它只重写了一个方法,并增加了一个可写实例变量,其余功能与dict完全相同[1]。它的构造签名为$defaultdict([default_factory[, ...]])$,第一个参数是工厂函数,其余参数按普通字典构造函数的方式处理。
普通dict在读取不存在的键时会触发KeyError异常,而defaultdict会用工厂函数的返回值填补这一空缺,因此它常被描述为一种不会因键缺失而报错的字典[2]。传入的工厂函数可以是int、list、set、str等内置类型,也可以是任意不带参数的可调用对象[3]。
原理
defaultdict的默认值机制依赖dict类自带的钩子方法__missing__。当通过下标读取一个不存在的键时,dict的__getitem__会转而调用__missing__(key),由子类决定返回什么或抛出什么异常[4]。defaultdict正是通过实现该方法获得默认值行为的,工厂函数本身存放在default_factory属性中。
其处理逻辑可以概括为:若default_factory为None,则按普通字典处理并抛出KeyError;否则不带参数调用该工厂函数,把得到的值作为该键的值存入字典并返回。若工厂函数自身抛出异常,异常会原样向外传递。
flowchart TD
A[执行 d[key]] --> B{key 是否在字典中}
B -- 是 --> C[返回已有值]
B -- 否 --> D{default_factory 是否为 None}
D -- 是 --> E[抛出 KeyError]
D -- 否 --> F[调用 default_factory 生成默认值]
F --> G[以 key 为键写入字典]
G --> H[返回该默认值]
工厂函数只在该键首次被读取时调用一次,之后该键已存在于字典中,后续访问直接返回已存的值。因此反复读取同一个缺失键不会不断产生新对象,而不同的缺失键则各自触发一次调用[5]。由于默认值会被真正写入字典,使用字典的get方法不会触发这一机制[6]。
发展历程
defaultdict随collections模块的扩展在Python 2.5中引入,同期dict类型也获得了__missing__钩子方法[4]。此前若要在旧版本中实现类似效果,只能自行继承dict并编写额外的取键逻辑[7]。
在标准库文档的早期版本中,collections模块仅包含deque与defaultdict两种数据类型,以及一个类型工厂函数namedtuple。该模块的文档与实现由Raymond Hettinger维护。
应用
最常见的用法是把工厂函数设为list,从而把一系列键值对按相同的键归并为字典列表。首次出现的键会自动获得一个空列表,随后的append操作把值追加进去;官方文档指出这种写法比使用dict.setdefault更简单也更快。
把工厂函数设为int可用于计数,因为不带参数调用int会返回0,每次遇到键时执行累加即可统计出现次数,效果类似于其他语言中的多重集合。若工厂函数为set,则键对应的值是一个集合,重复元素会被自动去重[3]。
在取值函数返回浮点数时,defaultdict同样可以用于对同一键的多笔数值求和[6]。在图结构的邻接表、日志聚合等键值不确定的场景中,这种类型可以省去逐键判断的样板代码[3]。
局限
defaultdict只能为不存在的键提供默认值,无法处理键已存在但取值为假的情况[8]。所有缺失的键共享同一套生成规则,它不支持针对不同键返回不同的默认值;如有此类需求,需要自行继承dict并改写__missing__[8]。
读取缺失键会顺带修改字典内容,这一点在只读遍历或并发访问时需要额外注意。用于并发场景时,仍然需要依赖dict本身的线程安全约束。
它不会减少哈希冲突、内存占用等字典本身的开销,默认值对象在大量键的情况下也会累积占用内存。构造时如果传入的是调用结果而非可调用对象,则会抛出TypeError,提示第一个参数必须是可调用的或None[6]。
参见
-
dict —— defaultdict所继承的Python内置字典类型
-
collections —— 定义defaultdict的Python标准库模块
-
KeyError —— 访问普通字典缺失键时抛出的异常
-
setdefault —— 字典自带的设置默认值方法,功能与defaultdict部分重叠
-
Counter —— collections模块中专用于计数的容器类型
参考资料
- defaultdict [引用日期2026-10-14]
- igadc.cn 上的网页 [引用日期2026-10-14]
- python-defaultdict [引用日期2026-10-14]
- 12 Other Language Changes [引用日期2026-10-14]
- 【Python进阶】可能是全网最详细的defaultdict讲解 [引用日期2026-10-14]
- 使用 Python defaultdict 类型处理丢失的键 [引用日期2026-10-14]
- 523034-emulate-collectionsdefaultdict [引用日期2026-10-14]
- Revision [引用日期2026-10-14]