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

如何用Python将规范化CSV反规范化为嵌套JSON

解决扁平JSON转嵌套数组(dataFields)的问题

问题描述

现有CSV转成的扁平JSON结构,其中dataFields.n.category这类键需要转换为嵌套数组dataFields,示例如下:

输入扁平JSON:

{"Example": [
    {"exCode": "example_code",
     "name": "ex",
     "code": "ex_2",
     "dataFields.0.category": "EXAMPLE",
     "dataFields.0.name": "exampl",
     "dataFields.0.code": "exampl",
     "dataFields.0.unit": "v",
     "dataFields.1.category": "EXAMPLE",
     "dataFields.1.name": "exampl2",
     "dataFields.1.code": "exampl2",
     "dataFields.1.unit": "e",
     "dataFields.2.category": "EXAMPLE2",
     "dataFields.2.name": null,
     "dataFields.2.code": null,
     "dataFields.2.unit": "e"
    }
]}

期望输出嵌套JSON:

{"Example": [
    {"exCode": "example_code",
     "name": "ex",
     "code": "ex_2",
     "dataFields": [
         {"category": "EXAMPLE", "name": "exampl", "code": "exampl", "unit": "v"},
         {"category": "EXAMPLE", "name": "exampl2", "code": "exampl2", "unit": "e"},
         {"category": "EXAMPLE2", "name": null, "code": null, "unit": "e"}
     ]
    }
]}

当前代码的核心问题是未正确处理数组索引,且未初始化dataFields数组,导致元素被覆盖。

问题分析

现有代码的几个关键错误:

  • 未初始化dataFields数组,直接调用append会抛出KeyError
  • 拆分键时忽略了数组索引(split_norm[1]),无法区分不同的数组元素
  • 错误地对字符串调用append(changes[3].append(...)),逻辑完全错误
  • 遍历字典键的方式混乱,未正确关联键值对

非递归解决方案

以下是修正后的非递归实现,逻辑清晰且能处理最多9个dataFields元素:

def denormalize_json(flat_json):
    # 遍历顶层的每个数组(比如示例中的"Example"对应的数组)
    for key in flat_json:
        items = flat_json[key]
        for item in items:
            # 初始化dataFields数组
            data_fields = []
            # 收集所有需要处理的扁平键
            flat_data_keys = [k for k in item if k.startswith("dataFields.")]
            
            for flat_key in flat_data_keys:
                # 拆分键:dataFields.n.key -> ["dataFields", "n", "key"]
                parts = flat_key.split(".")
                if len(parts) != 3:
                    continue  # 跳过格式不正确的键
                idx = int(parts[1])
                field_name = parts[2]
                field_value = item[flat_key]
                
                # 确保data_fields的长度足够容纳当前索引
                while len(data_fields) <= idx:
                    data_fields.append({})
                # 给对应索引的字典添加字段
                data_fields[idx][field_name] = field_value
                # 删除原扁平键
                del item[flat_key]
            
            # 将嵌套数组添加回原条目
            if data_fields:
                item["dataFields"] = data_fields
    return flat_json

# 测试示例
if __name__ == "__main__":
    input_json = {
        "Example": [
            {
                "exCode": "example_code",
                "name": "ex",
                "code": "ex_2",
                "dataFields.0.category": "EXAMPLE",
                "dataFields.0.name": "exampl",
                "dataFields.0.code": "exampl",
                "dataFields.0.unit": "v",
                "dataFields.1.category": "EXAMPLE",
                "dataFields.1.name": "exampl2",
                "dataFields.1.code": "exampl2",
                "dataFields.1.unit": "e",
                "dataFields.2.category": "EXAMPLE2",
                "dataFields.2.name": None,
                "dataFields.2.code": None,
                "dataFields.2.unit": "e"
            }
        ]
    }
    
    result = denormalize_json(input_json)
    import json
    print(json.dumps(result, indent=2))

代码说明

  1. 初始化数组:对每个条目先创建空的data_fields数组,用于存放嵌套对象
  2. 筛选扁平键:只处理以dataFields.开头的键,避免干扰其他字段
  3. 拆分键并处理索引:通过拆分键获取数组索引idx,确保数组长度足够后,将键值对存入对应索引的字典
  4. 清理与替换:删除原扁平键,将嵌套数组添加回原条目

运行上述代码后,即可得到期望的嵌套JSON结构,且不会出现元素覆盖的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:50:24