如何动态在嵌套层级的Python字典中插入JSON对象?
问题描述
我正在编写一个基于JSON规范生成测试数据的脚本,目标是构建JSON对象/Python字典record。为简化操作,使用列表items表示源条目,同时代表值的插入路径。
预期输出
{ "access": { "device": { "java": { "version": "Test Data" }, "python": { "version": "Test Data" } }, "type": "Test Data" }, "item1": 1, "item2": 0 }
目前能构建嵌套对象,但它们都被插入到字典的第一层。请问如何将结果存储到预期的嵌套位置?
源代码
import json import random def get_nested_obj(items: list): """ Construct a nested json object """ res = 'Test Data' for item in items[::-1]: res = {item: res} return res def get_dest_path(source_fields): """ Construct dest path where result from `get_nested_obj` should go """ dest_path = '' for x in source_fields: dest_path += f'[\'{x}\']' return 'record'+dest_path record = {} items = ['access.device.java.version', 'access.device.python.version', 'access.type', 'item1', 'item2'] for item in items: if '.' in item: source_fields = item.split('.') temp = record for i, source_field in enumerate(source_fields): if source_field in temp: temp = temp[source_field] continue res = get_nested_obj(source_fields[i+1:]) dest_path = get_dest_path(source_fields[:i]) print(dest_path) record[source_field] = res # Here's the problem. How to use dest_path here? break else: record[item] = random.randint(0, 1) print(json.dumps(record))
当前输出
{ "access": { "device": { "java": { "version": "Test Data" } } }, "python": { "version": "Test Data" }, "type": "Test Data", "item1": 1, "item2": 0 }
解决方案
核心问题分析
原代码中直接使用record[source_field] = res会将嵌套对象插入到字典顶层,而不是预期的嵌套路径里。你不需要通过dest_path字符串拼接的方式操作字典,直接利用temp这个指向当前层级字典的指针即可完成嵌套赋值。
方案一:简化逻辑,直接逐层构建路径
import json import random def get_nested_obj(items: list): """ 构建嵌套JSON对象 """ res = 'Test Data' for item in items[::-1]: res = {item: res} return res record = {} items = ['access.device.java.version', 'access.device.python.version', 'access.type', 'item1', 'item2'] for item in items: if '.' in item: source_fields = item.split('.') temp = record # 遍历路径到倒数第二层,确保每一层的字典都存在 for field in source_fields[:-1]: if field not in temp: temp[field] = {} temp = temp[field] # 给最后一层字段赋值 temp[source_fields[-1]] = 'Test Data' else: record[item] = random.randint(0, 1) print(json.dumps(record, indent=4))
方案二:保留原函数,修改赋值目标
如果你想保留原来的get_nested_obj函数,只需把赋值语句从record[source_field] = res改成temp[source_field] = res,因为temp此时指向的是当前需要插入的层级字典:
import json import random def get_nested_obj(items: list): """ Construct a nested json object """ res = 'Test Data' for item in items[::-1]: res = {item: res} return res record = {} items = ['access.device.java.version', 'access.device.python.version', 'access.type', 'item1', 'item2'] for item in items: if '.' in item: source_fields = item.split('.') temp = record for i, source_field in enumerate(source_fields): if source_field in temp: temp = temp[source_field] continue res = get_nested_obj(source_fields[i+1:]) # 关键修改:给当前层级的temp赋值,而非顶层record temp[source_field] = res break else: record[item] = random.randint(0, 1) print(json.dumps(record, indent=4))
效果说明
两种方案都能生成你预期的嵌套结构,核心思路是通过temp指针跟踪当前操作的字典层级,确保嵌套对象被插入到正确的位置,而非顶层字典。
内容的提问来源于stack exchange,提问作者Prashanth kumar
相关产品推荐
相关产品推荐

