Python嵌套字典列表追加异常:dict.fromkeys初始化的同引用问题
问题根因
输出异常的核心原因是dict.fromkeys()的可变参数共享引用机制:
- 当使用
dict.fromkeys(键列表, 默认值)构造字典时,如果默认值是列表、字典这类可变对象,方法不会为每个键单独创建默认值副本,而是让所有键的value都指向同一个内存地址的对象 - 你的代码里,分组1和分组2的
words列表实际是同一个共享列表,所有append操作都是在修改这个公共列表,最终才会出现两个分组的内容完全一致的问题
可以用极简代码复现该特性:
demo = dict.fromkeys(['g1', 'g2'], []) demo['g1'].append('test') print(demo) # 输出:{'g1': ['test'], 'g2': ['test']}
解决方案
只要保证每个分组对应的嵌套字典/列表是独立创建、没有共享引用即可,提供3种可直接运行的实现方式:
用字典推导式替代
dict.fromkeys()初始化分组结构
字典推导式在循环生成键值对时,会为每个键独立创建嵌套对象,从根源避免引用共享:group_identifier = [1,2,1] word_list = ['a', 'big', 'problem'] # 先提取所有不重复的分组ID,逐个初始化独立结构 unique_groups = set(group_identifier) word_dict = {group_id: {'words': []} for group_id in unique_groups} for word, group in zip(word_list, group_identifier): word_dict[group]['words'].append(word) print(word_dict) # 输出结果完全符合预期:{1: {'words': ['a', 'problem']}, 2: {'words': ['big']}}遍历过程中动态判断分组是否存在
不需要提前提取所有分组ID,遇到新分组时再初始化独立结构即可,适配动态生成分组的场景:group_identifier = [1,2,1] word_list = ['a', 'big', 'problem'] word_dict = {} for word, group in zip(word_list, group_identifier): if group not in word_dict: word_dict[group] = {'words': []} word_dict[group]['words'].append(word)借助
collections.defaultdict简化初始化逻辑
给defaultdict传入一个返回独立嵌套结构的工厂函数,遇到未记录的分组时会自动生成独立的结构,简化判断逻辑:from collections import defaultdict group_identifier = [1,2,1] word_list = ['a', 'big', 'problem'] # 工厂函数每次被调用时都会生成新的独立{'words': []}结构 word_dict = defaultdict(lambda: {'words': []}) for word, group in zip(word_list, group_identifier): word_dict[group]['words'].append(word) # 如果需要转换为普通字典,可执行:word_dict = dict(word_dict)
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

