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

如何动态在嵌套层级的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:40:31