You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中以指定字典为默认值的嵌套defaultdict出现字典实例共享问题

问题根源分析

嘿,这问题太典型了——你踩了Python可变对象引用的坑!

你定义的counter_format是一个可变字典对象,然后在嵌套defaultdict的lambda里直接返回它。这意味着所有新生成的嵌套字典,其实都指向同一个内存地址的counter_format对象。不管你修改哪个路径下的correct值,本质上都是在修改同一个字典,所以最后所有地方的数值都变成了3。

修复方案

解决思路很简单:每次需要默认值时,返回一个全新的字典实例,而不是复用同一个对象。这里有几种靠谱的实现方式:

方案1:直接在lambda里定义新字典

最直接的写法,省去单独的counter_format变量:

from collections import defaultdict
userDict = defaultdict(lambda: defaultdict(lambda: {"correct": 0, "incorrect": 0}))

方案2:复用模板字典+浅拷贝

如果你想保留counter_format作为模板(比如后续要修改模板结构),可以用copy()方法每次生成新字典:

from collections import defaultdict
counter_format = {"correct": 0, "incorrect": 0}
userDict = defaultdict(lambda: defaultdict(lambda: counter_format.copy()))

注:这里用浅拷贝就足够,因为你的字典值都是不可变的整数。如果模板字典里还有嵌套可变对象,就得用deepcopy了。

方案3:用数据类生成新实例(更优雅)

如果你的计数器结构后续可能扩展,用dataclasses会更清晰,每次生成新实例再转成字典:

from dataclasses import dataclass, asdict
from collections import defaultdict

@dataclass
class Counter:
    correct: int = 0
    incorrect: int = 0

userDict = defaultdict(lambda: defaultdict(lambda: asdict(Counter())))
验证效果

运行你原来的测试代码:

userDict['a'][1]['correct'] += 1
userDict['b'][1]['correct'] += 1
userDict['b'][2]['correct'] += 1

现在每个correct值都会独立更新,结果符合预期:

defaultdict(<function <lambda> at 0x10ca85ee0>, {
    'a': defaultdict(<function <lambda>.<locals>.<lambda> at 0x10cbc0430>, {1: {'correct': 1, 'incorrect': 0}}),
    'b': defaultdict(<function <lambda>.<locals>.<lambda> at 0x10cbc0b80>, {
        1: {'correct': 1, 'incorrect': 0},
        2: {'correct': 1, 'incorrect': 0}
    })
})

内容的提问来源于stack exchange,提问作者jbogart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 17:12:30