如何在for循环中创建嵌套字典(不使用defaultdict)?
嵌套字典分组数据问题解决建议
输入数据
test_file = [['ref1', 'test1', 2], ['ref2', 'test1', 3], ['ref3', 'test2', 4], ['ref1', 'test2', 4], ['ref2', 'test2', 1], ['ref1', 'test1', 4], ['ref1', 'test1', 5]]
目标输出说明
你写的desired_output存在重复键(比如多个'ref1'),这在Python字典里是不合法的,重复键会被最后一个覆盖。实际合理的目标结构应该是每个ref对应一个字典,里面包含所有test类型的键和对应的值列表:
desired_output = { 'ref1': {'test1': [2, 4, 5], 'test2': [4]}, 'ref2': {'test1': [3], 'test2': [1]}, 'ref3': {'test2': [4]} }
你遇到的问题
尝试用defaultdict时触发错误:
AttributeError: 'collections.defaultdict' object has no attribute 'append'
之后你写的代码:
for entry in test_file: nest1 = {} try: nest1[entry[1]].append(entry[2]) except KeyError: nest1[entry[1]] = [entry[2]] try: mynestdict[entry[0]].append(nest1) except KeyError: mynestdict[entry[0]] = [nest1] print(dict(mynestdict))
得到的输出是每个ref对应一个小字典的列表,而不是合并后的嵌套字典:
{'ref1': [{'test1': [2]}, {'test2': [4]}, {'test1': [4]}, {'test1': [5]}], 'ref2': [{'test1': [3]}, {'test2': [1]}], 'ref3': [{'test2': [4]}]}
解决方法
方法1:普通字典+嵌套判断
直接用普通字典,通过判断键是否存在来逐步构建结构:
mynestdict = {} for ref, test, val in test_file: # 外层:如果当前ref不在字典中,创建空字典作为值 if ref not in mynestdict: mynestdict[ref] = {} # 内层:如果当前test不在ref对应的字典中,创建空列表作为值 if test not in mynestdict[ref]: mynestdict[ref][test] = [] # 把值追加到对应列表里 mynestdict[ref][test].append(val) print(mynestdict)
运行后就能得到目标结构的嵌套字典。
方法2:嵌套使用defaultdict
之前用defaultdict出错是因为没正确嵌套层级。我们可以让外层defaultdict的默认值是另一个defaultdict,而内层defaultdict的默认值是列表,这样就能直接调用append:
from collections import defaultdict # 外层字典:key不存在时生成值为defaultdict(list)的字典 # 内层字典:key不存在时生成空列表 mynestdict = defaultdict(lambda: defaultdict(list)) for ref, test, val in test_file: mynestdict[ref][test].append(val) # 可选:转换成普通字典输出 print(dict(mynestdict))
这种写法更简洁,不需要手动判断键是否存在。
错误原因解释
- 最初
defaultdict用法错误:你可能误把外层defaultdict的默认值设成了普通字典,或者试图给defaultdict对象本身调用append,而不是给内层的列表调用。 - 后来的代码逻辑问题:每次循环都新建一个
nest1小字典,然后把它追加到外层的列表里,导致同一个ref下的test条目没有合并,而是变成了多个独立的小字典。
内容的提问来源于stack exchange,提问作者Fcallejas
相关产品推荐
相关产品推荐

