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

如何用Python3实现含嵌套列表的复杂字典扁平化(键以点分隔)

解决嵌套字典含列表的扁平化笛卡尔积转换问题

你的需求是将包含嵌套字典和多层列表的输入,转换为所有列表元素笛卡尔积组合的扁平化字典列表——每个列表的每个元素都要和其他列表的元素一一组合,同时保留所有非列表的公共字段。

现有代码的问题

  • 仅处理了第一层列表,无法递归处理嵌套在字典内部的列表(比如key4nestedListOfDict里的subkeyNested)
  • 没有处理多个列表的笛卡尔积逻辑,只是逐个展开列表,无法生成所有组合的结果

解决方案代码

from collections.abc import MutableMapping
from itertools import product
import json

def split_common_and_lists(data, parent_key='', separator='.'):
    common = {}
    list_dims = []  # 存储每个列表维度的可选键值对集合
    
    for key, value in data.items():
        current_key = f"{parent_key}{separator}{key}" if parent_key else key
        
        if isinstance(value, MutableMapping):
            # 递归处理嵌套字典,合并公共部分和列表维度
            sub_common, sub_lists = split_common_and_lists(value, current_key, separator)
            common.update(sub_common)
            list_dims.extend(sub_lists)
        elif isinstance(value, list):
            # 处理列表:生成该维度的所有可选键值组合
            options = []
            for item in value:
                if isinstance(item, (MutableMapping, list)):
                    # 递归展开列表元素内部的嵌套结构
                    item_common, item_lists = split_common_and_lists(item, current_key, separator)
                    if item_lists:
                        # 元素内部有子列表,计算子维度的笛卡尔积并合并
                        for sub_comb in product(*item_lists):
                            combined = item_common.copy()
                            for sub_dict in sub_comb:
                                combined.update(sub_dict)
                            options.append(combined)
                    else:
                        options.append(item_common)
                else:
                    # 列表元素为普通值,直接生成键值对
                    options.append({current_key: value})
            list_dims.append(options)
        else:
            # 普通键值对加入公共部分
            common[current_key] = value
    
    return common, list_dims

def flatten_to_cartesian_list(data):
    common, list_dims = split_common_and_lists(data)
    
    if not list_dims:
        return [common]
    
    # 计算所有列表维度的笛卡尔积,生成最终结果
    result = []
    for combo in product(*list_dims):
        row = common.copy()
        for part in combo:
            row.update(part)
        result.append(row)
    
    return result

# 测试示例
input_data = {
    'key1': 1, 
    'key2dict': {'subkey1': 1, 'subkey2': 2},
    'key3listOfDict': [
        {'subkey3': 3, 'subkey4': 4},
        {'subkey5': 5, 'subkey6': 6}
    ],
    'key4nestedListOfDict': [
        {
            'subkey7': 7, 
            'subkeyNested': [
                {'subkey8': 8}, 
                {'subkey9': 9}
            ]
        }
    ]
}

output = flatten_to_cartesian_list(input_data)
print(json.dumps(output, indent=2))

代码说明

  1. split_common_and_lists函数:
    • 递归遍历输入数据,分离出所有非列表的公共键值对(存入common)
    • 遇到列表时,将列表中每个元素展开为扁平化的键值对字典;如果元素内部还有嵌套列表,会递归计算子维度的笛卡尔积,生成该元素的所有可能组合,最终将整个列表的所有选项存入list_dims
  2. flatten_to_cartesian_list函数:
    • 使用itertools.product计算所有列表维度的笛卡尔积,将每个组合的键值对与公共部分合并,生成最终的字典列表

运行上述代码后,会输出你需要的4个扁平化字典的列表,完全匹配预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:42:03