代码改变世界

defaultdict - 指南

2026-01-03 09:37  tlnshuju  阅读(24)  评论(0)    收藏  举报

defaultdict 是 Python 标准库 collections 模块中的一个非常有用的类,它继承自内置的 dict 类,在处理字典操作时提供了一些额外的便利。下面从基本概念、使用方法、应用场景等方面详细解释 defaultdict

基本概念

在普通的 Python 字典中,如果尝试访问一个不存在的键,会引发 KeyError 异常。而 defaultdict 则不同,它允许你在创建字典时指定一个默认值的工厂函数。当访问一个不存在的键时,defaultdict 会自动调用这个工厂函数来创建一个默认值,并将该键值对插入到字典中,从而避免了 KeyError 异常的发生。

使用方法

1. 导入 defaultdict

要使用 defaultdict,首先需要从 collections 模块中导入它:

from collections import defaultdict
2. 创建 defaultdict 对象

创建 defaultdict 对象时,需要传入一个可调用对象(通常是一个函数)作为默认值的工厂函数。以下是一些常见的示例:

示例 1:使用 int 作为默认值工厂
from collections import defaultdict
# 创建一个默认值为 0 的 defaultdict
d = defaultdict(int)
# 访问不存在的键
print(d['key'])  # 输出: 0
# 插入键值对
d['apple'] = 5
print(d['apple'])  # 输出: 5

在这个例子中,我们使用 int 作为默认值工厂。int() 调用会返回 0,所以当访问不存在的键时,defaultdict 会自动将该键的值初始化为 0。

注:
defaultdict 要求你传入一个可调用对象(像函数、类)作为默认值工厂。当你访问一个不存在的键时,defaultdict 就会调用这个可调用对象,就如同工厂生产产品一样,生成一个默认值给这个不存在的键。

当你使用 defaultdict(int) 创建一个字典时,若尝试访问一个字典里不存在的键,defaultdict 会自动调用 int() 来生成一个默认值。因为 int() 调用后会返回整数 0,所以这个字典里不存在的键对应的默认值就是 0。

示例 2:使用 list 作为默认值工厂
from collections import defaultdict
# 创建一个默认值为 [] 的 defaultdict
d = defaultdict(list)
# 访问不存在的键
print(d['key'])  # 输出: []
# 向列表中添加元素
d['fruits'].append('apple')
d['fruits'].append('banana')
print(d['fruits'])  # 输出: ['apple', 'banana']

这里使用 list 作为默认值工厂。list() 调用会返回一个空列表,所以当访问不存在的键时,defaultdict 会自动将该键的值初始化为一个空列表。

示例 3:使用自定义函数作为默认值工厂
from collections import defaultdict
# 定义一个自定义的默认值工厂函数
def default_value():
    return 'default'
# 创建一个使用自定义默认值的 defaultdict
d = defaultdict(default_value)
# 访问不存在的键
print(d['key'])  # 输出: 'default'

在这个例子中,我们定义了一个自定义的函数 default_value 作为默认值工厂。当访问不存在的键时,defaultdict 会调用这个函数来创建默认值。

在Python的collections.defaultdict中,除了intlist和自定义函数外,还支持多种内置类型和标准库类型作为工厂函数。

一、基础数据类型
  1. str(字符串)
    默认值为空字符串"",适用于字符串拼接场景:
    from collections import defaultdict
    d = defaultdict(str)
    d["name"] += "Alice"  # 无需先初始化键
    print(d["name"])  # 输出: "Alice"
  2. float(浮点数)
    默认值为0.0,适用于数值累计:
    d = defaultdict(float)
    d["score"] += 95.5  # 初始值为0.0,累加后为95.5
  3. dict(字典)
    默认值为空字典{}, 适用于嵌套字典结构:
    d = defaultdict(dict)
    d["user"]["name"] = "Bob"  # 直接为嵌套键赋值
  4. set(集合)
    默认值为空集合set(),适用于去重或集合操作:
    d = defaultdict(set)
    d["tags"].add("python")  # 无需先初始化集合
二、标准库特殊类型
  1. collections.deque(双端队列)
    适用于高效的首尾元素操作:
    from collections import defaultdict, deque
    d = defaultdict(deque)
    d["tasks"].appendleft("priority")  # 左侧添加元素
  2. collections.Counter(计数器)
    用于嵌套计数场景:
    from collections import defaultdict, Counter
    d = defaultdict(Counter)
    d["words"]["hello"] += 1  # 对嵌套键进行计数
  3. list的变体(如collections.namedtuple
    需注意:namedtuple本身是工厂函数,需先定义类型再使用:
    from collections import defaultdict, namedtuple
    Person = namedtuple("Person", ["name", "age"])
    d = defaultdict(lambda: Person("", 0))  # 用lambda初始化默认值
三、其他可调用对象
  • lambda表达式:自定义默认值,例如defaultdict(lambda: "N/A")(默认值为"N/A")。
  • 类构造函数:如datetime.date(需配合lambda传参):
    from datetime import date
    d = defaultdict(lambda: date(2023, 1, 1))  # 默认日期为2023-01-01
核心原理总结

defaultdict的工厂函数需满足无参数调用(如int()返回0list()返回[])。因此,带参数的类型(如list(10))需通过lambda包装为无参调用

应用场景

1. 统计元素出现次数

可以使用 defaultdict(int) 来统计列表中每个元素的出现次数:

from collections import defaultdict
lst = [1, 2, 3, 2, 1, 3, 1]
count = defaultdict(int)
for num in lst:
    count[num] += 1
print(count)  # 输出: defaultdict(, {1: 3, 2: 2, 3: 2})
2. 分组元素

使用 defaultdict(list) 可以将列表中的元素按照某个规则进行分组:

from collections import defaultdict
words = ['apple', 'banana', 'cherry', 'avocado']
grouped = defaultdict(list)
for word in words:
    grouped[word[0]].append(word)
print(grouped)  # 输出: defaultdict(, {'a': ['apple', 'avocado'], 'b': ['banana'], 'c': ['cherry']})

总结

defaultdict 是一个强大的工具,它通过提供默认值的工厂函数,避免了在访问不存在的键时引发 KeyError 异常,使得代码更加简洁和健壮。在处理需要频繁初始化默认值的字典操作时,defaultdict 可以大大提高代码的可读性和效率。