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

如何递归修改嵌套字典的name键值为父节点拼接路径?

嵌套字典结构中递归拼接节点name路径的实现方法

问题描述

需要处理如下嵌套数据结构:

payload = {
   "name":"Event1",
   "events":[
      {
         "name":"A",
         "data":[
            {
               "name":"subscriptionId",
               "data_id":0,
               "data":0
            },
            {
               "name":"updateCounter",
               "data_id":1,
               "data":0
            },
            {
               "name":"noOfMessages",
               "data_id":2,
               "data":0
            },
            {
               "name":"counter",
               "data_id":3,
               "data":0
            },
            {
               "name":"resourceElements",
               "data_id":4,
               "data":0
            },
            {
               "name":"type",
               "data_id":5,
               "data":0
            },
            {
               "name":"subscription",
               "data_id":6,
               "data":0
            },
            {
               "name":"element",
               "data_id":7,
               "data":[
                  {
                     "name":"type",
                     "data_id":0,
                     "data":0
                  },
                  {
                     "name":"plugLockState",
                     "data_id":1,
                     "data":{
                        "value":""
                     }
                  },
                  {
                     "name":"lockState",
                     "data_id":2,
                     "data":{
                        "value":""
                     }
                  },
                  {
                     "name":"flapState",
                     "data_id":6,
                     "data":{
                        "value":""
                     }
                  },
                  {
                     "name":"plugState",
                     "data_id":3,
                     "data":0
                  },
                  {
                     "name":"plugConnectionState",
                     "data_id":4,
                     "data":0
                  },
                  {
                     "name":"infrastructureState",
                     "data_id":5,
                     "data":0
                  }
               ]
            }
         ]
      }
   ]
}

期望将结构中每个节点的name键值修改为父节点路径拼接的形式,理想结果如下:

{
   "name":"Event1",
   "events":[
      {
         "name":"Event1.A",
         "data":[
            {
               "name":"Event1.A.subscriptionId",
               "data_id":0,
               "data":0
            },
            {
               "name":"Event1.A.updateCounter",
               "data_id":1,
               "data":0
            },
            {
               "name":"Event1.A.noOfMessages",
               "data_id":2,
               "data":0
            },
            {
               "name":"Event1.A.counter",
               "data_id":3,
               "data":0
            },
            {
               "name":"Event1.A.resourceElements",
               "data_id":4,
               "data":0
            },
            {
               "name":"Event1.A.type",
               "data_id":5,
               "data":0
            },
            {
               "name":"Event1.A.subscription",
               "data_id":6,
               "data":0
            },
            {
               "name":"Event1.A.element",
               "data_id":7,
               "data":[
                  {
                     "name":"Event1.A.element.type",
                     "data_id":0,
                     "data":0
                  },
                  {
                     "name":"Event1.A.element.plugLockState",
                     "data_id":1,
                     "data":{
                        "value":""
                     }
                  },
                  {
                     "name":"Event1.A.element.lockState",
                     "data_id":2,
                     "data":{
                        "value":""
                     }
                  },
                  {
                     "name":"Event1.A.element.flapState",
                     "data_id":6,
                     "data":{
                        "value":""
                     }
                  },
                  {
                     "name":"Event1.A.element.plugState",
                     "data_id":3,
                     "data":0
                  },
                  {
                     "name":"Event1.A.element.plugConnectionState",
                     "data_id":4,
                     "data":0
                  },
                  {
                     "name":"Event1.A.element.infrastructureState",
                     "data_id":5,
                     "data":0
                  }
               ]
            }
         ]
      }
   ]
}

目前已编写如下递归方法,但不清楚如何在递归遍历的同时按需求修改name键值:

def iterate_recursively(dictionary: dict, names=None):
    if names is None:
        names = []
    for k, v in dictionary.items():
        if isinstance(v, dict):
            iterate_recursively(v)
        elif isinstance(v, list):
            for d in v:
                if isinstance(d, dict):
                    names.append(d["name"])
                    iterate_recursively(d)

解决方案

你的现有递归逻辑存在两个核心问题:一是没有传递当前的路径前缀,二是缺少修改name的具体逻辑。可以通过以下方式实现需求:

修正后的递归函数

def update_names_recursively(node, parent_path=""):
    # 处理包含name字段的字典节点
    if isinstance(node, dict) and "name" in node:
        # 拼接新的name:父路径为空时直接用当前name,否则用父路径+当前name
        if parent_path:
            node["name"] = f"{parent_path}.{node['name']}"
        # 将当前节点的完整路径作为子节点的父路径
        current_path = node["name"]
        
        # 遍历当前节点的所有子元素,递归处理
        for key, value in node.items():
            if isinstance(value, dict):
                update_names_recursively(value, current_path)
            elif isinstance(value, list):
                for item in value:
                    update_names_recursively(item, current_path)

# 调用函数处理目标结构
update_names_recursively(payload)

逻辑说明

  1. 路径传递:每次递归时,将当前节点的完整路径(已拼接后的name)作为parent_path传递给子节点,确保子节点能基于父路径生成自己的完整路径。
  2. 修改时机:优先处理包含name字段的字典节点,先更新该节点的name值,再以更新后的路径为前缀,处理该节点下的所有子元素(字典或列表中的字典)。
  3. 列表处理:遇到列表类型的子元素时,遍历列表中的每个项,对其中的字典节点递归执行路径拼接逻辑,确保嵌套在列表中的子节点也能正确生成完整路径。

验证结果

调用上述函数后,payload的结构会完全符合你给出的理想结果,每个节点的name都会是从根节点到当前节点的完整路径拼接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:40:44