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

如何将多层Python字典展开为字典列表?

问题描述

我有一个多层Python字典作为输入:第一层代表坐标(如x、y、angle_z等),第二层是该坐标的所有可能取值,后续层级代表当前坐标固定时需变更的其他坐标,依此类推。

输入字典

dictionary = {
    'x': {
        1: {
            'y': {
                1: {'angle_z': 3},
                4: {'angle_z': 5}
            }
        },
        2: {
            'z': {
                3: {'angle_y': 2}
            }
        }
    },
    'z': {
        2: {'y': 10}
    }
}

预期输出

[{'x': 1, 'y': 1, 'angle_z': 3}, 
 {'x': 1, 'y': 4, 'angle_z': 5},
 {'x': 2, 'z': 3, 'angle_y': 2},
 {'z': 2, 'y': 10}]

要求每个坐标在序列中仅出现一次(如{'x':{1:{'x':2}}}这类情况不允许),函数需尽可能通用,不依赖具体坐标名称,支持任意层数的字典。

我的尝试

我写的递归函数输出结果与预期相差甚远:

def unpack_dictionary(dictionary):
    if isinstance(dictionary, dict):
        if len(dictionary) == 1:
            key = next(iter(dictionary))
            rest = dictionary[key]
            sub_results = unpack_dictionary(rest)
            return [{key: value, **sub_dict} for value in sub_results for sub_dict in sub_results]
        else:
            results = []
            for key, value in dictionary.items():
                sub_results = unpack_dictionary(value)
                for sub_dict in sub_results:
                    sub_dict[key] = value
                    results.append(sub_dict)
            return results
    else:
        return [{}]

错误输出

[{'y': {'angle_z': {}, 1: {'angle_z': 3}},
  'angle_z': {},
  1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
  'x': {1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
   2: {'z': {3: {'angle_y': 2}}}}},
 {'y': {'angle_z': {}, 1: {'angle_z': 3}},
  'angle_z': {},
  4: {'angle_z': 5},
  1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
  'x': {1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
   2: {'z': {3: {'angle_y': 2}}}}},
 {'y': {'angle_z': {}, 4: {'angle_z': 5}},
  'angle_z': {},
  1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
  'x': {1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
   2: {'z': {3: {'angle_y': 2}}}}},
 {'y': {'angle_z': {}, 4: {'angle_z': 5}},
  'angle_z': {},
  4: {'angle_z': 5},
  1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
  'x': {1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
   2: {'z': {3: {'angle_y': 2}}}}},
 {'z': {3: {'angle_y': {}}, 'angle_y': {}},
  3: {'angle_y': {}},
  'angle_y': {},
  2: {'z': {3: {'angle_y': 2}}},
  'x': {1: {'y': {1: {'angle_z': 3}, 4: {'angle_z': 5}}},
   2: {'z': {3: {'angle_y': 2}}}}},
 {2: {'y': {}}, 'y': {}, 'z': {2: {'y': 10}}}]
解决方案

你的代码核心问题是混淆了字典层级关系,错误地将父级键值嵌套到子结果中,且列表推导式重复遍历子结果导致冗余数据。以下是正确的递归实现:

正确代码

def unpack_dict(input_dict, current=None):
    if current is None:
        current = {}
    results = []
    for key, value in input_dict.items():
        if isinstance(value, dict):
            # 遍历当前坐标的所有可能取值
            for val, sub_dict in value.items():
                # 复制当前累积字典,避免分支间互相干扰
                new_current = current.copy()
                new_current[key] = val
                # 递归处理子字典,合并结果
                results.extend(unpack_dict(sub_dict, new_current))
        else:
            # 叶子节点,生成完整坐标组合
            new_current = current.copy()
            new_current[key] = value
            results.append(new_current)
    return results

# 测试示例
dictionary = {
    'x': {
        1: {
            'y': {
                1: {'angle_z': 3},
                4: {'angle_z': 5}
            }
        },
        2: {
            'z': {
                3: {'angle_y': 2}
            }
        }
    },
    'z': {
        2: {'y': 10}
    }
}

print(unpack_dict(dictionary))

输出结果

[{'x': 1, 'y': 1, 'angle_z': 3}, {'x': 1, 'y': 4, 'angle_z': 5}, {'x': 2, 'z': 3, 'angle_y': 2}, {'z': 2, 'y': 10}]

代码说明

  • 每次递归复制当前累积字典,避免不同分支的坐标组合互相污染。
  • 区分嵌套字典节点和叶子节点:嵌套节点继续递归遍历取值,叶子节点直接生成完整组合。
  • 顶层自动遍历所有根坐标(如示例中的x和z),各自展开后合并所有结果。
  • 天然满足“每个坐标仅出现一次”的要求,因为递归路径中每个坐标只会被添加一次到累积字典(前提是输入字典本身无重复坐标)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 13:12:53