如何在Python中将JSON指定键值替换为列表(基于jsondiff结果)
问题描述
使用jsondiff对比两个JSON后得到差异结果:
{'Functions': {0: {'Function-1': {0: {'Function': 'dd', 'Function2': 'd3'}}}}}
需要将结果中所有{0: }结构移除,把对应的值包裹为列表,最终得到目标格式:
{"Functions":[{"Function-1":[{"Function":"dd","Function2":"d3"}]}]}
由于差异结果会随JSON内容动态变化,无法通过简单字符串替换实现,寻求通用解决方案。当前使用的Python代码如下:
from jsondiff import diff import json json1 = json.loads(""" { "Name": "Temperature \u0026 Pressure Measurement", "Id": "0x0102", "Channels": [ { "Data": [ { "Channel0": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel1": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel2": [ { "Enable": 0, "Unit": "Celsius" } ] } ] } ], "Events": [ { "event1": 0, "event2": 0 } ], "Diagnostics": [ { "diag1": 0, "diag2": 0 } ], "Functions": [ { "Function-1": [ { "Function": "2d" } ] } ] } """) json2 = json.loads(""" { "Name": "Temperature \u0026 Pressure Measurement", "Id": "0x0102", "Channels": [ { "Data": [ { "Channel0": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel1": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel2": [ { "Enable": 0, "Unit": "Celsius" } ] } ] } ], "Events": [ { "event1": 0, "event2": 0 } ], "Diagnostics": [ { "diag1": 0, "diag2": 0 } ], "Functions": [ { "Function-1": [ { "Function": "dd", "Function2":"d3" } ] } ] } """) # 当前仅将差异转为字符串,无法处理动态结构 res = str(diff(json1, json2)) print('----------------------') print('------- DIFF -------') print('----------------------') print(f'{res}') print('----------------------') print('----------------------') print('') print('----------------------') print('---Expected Output---') print('----------------------') print('{"Functions":[{"Function-1":[{"Function":"dd","Function2":"d3"}]}]}') print('----------------------') print('----------------------')
解决方案
核心思路是直接操作jsondiff返回的字典对象(而非转成字符串),通过递归遍历处理所有嵌套的{0: 值}结构,将其替换为[值]。具体实现如下:
- 编写递归处理函数:遍历字典的每个键值对,若键为
0,则将对应值递归处理后包裹为列表;若值是字典,则继续递归处理;其他情况保持原结构。 - 避免将diff结果转为字符串,直接对字典进行处理,最后转为JSON字符串得到目标格式。
修改后的完整代码:
from jsondiff import diff import json def transform_diff(data): if isinstance(data, dict): # 处理{0: ...}的结构,转为列表 if len(data) == 1 and 0 in data: return [transform_diff(data[0])] # 递归处理普通字典的每个值 return {k: transform_diff(v) for k, v in data.items()} elif isinstance(data, list): # 递归处理列表中的每个元素 return [transform_diff(item) for item in data] else: # 基础类型直接返回 return data json1 = json.loads(""" { "Name": "Temperature \u0026 Pressure Measurement", "Id": "0x0102", "Channels": [ { "Data": [ { "Channel0": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel1": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel2": [ { "Enable": 0, "Unit": "Celsius" } ] } ] } ], "Events": [ { "event1": 0, "event2": 0 } ], "Diagnostics": [ { "diag1": 0, "diag2": 0 } ], "Functions": [ { "Function-1": [ { "Function": "2d" } ] } ] } """) json2 = json.loads(""" { "Name": "Temperature \u0026 Pressure Measurement", "Id": "0x0102", "Channels": [ { "Data": [ { "Channel0": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel1": [ { "Enable": 0, "Unit": "Celsius" } ], "Channel2": [ { "Enable": 0, "Unit": "Celsius" } ] } ] } ], "Events": [ { "event1": 0, "event2": 0 } ], "Diagnostics": [ { "diag1": 0, "diag2": 0 } ], "Functions": [ { "Function-1": [ { "Function": "dd", "Function2":"d3" } ] } ] } """) # 直接获取diff字典,不转字符串 diff_result = diff(json1, json2) # 转换结构 transformed = transform_diff(diff_result) # 转为JSON字符串 output = json.dumps(transformed) print('----------------------') print('------- DIFF -------') print('----------------------') print(diff_result) print('----------------------') print('----------------------') print('') print('----------------------') print('---Transformed Output---') print('----------------------') print(output) print('----------------------') print('----------------------')
说明
- 递归函数
transform_diff可以处理任意嵌套深度的{0: 值}结构,无论差异结果如何动态变化,都能正确转换为列表格式。 - 最终输出的JSON字符串与目标格式完全一致,且支持更复杂的差异场景(比如多个列表元素的修改)。
内容的提问来源于stack exchange,提问作者DeLorean
相关产品推荐
相关产品推荐

