通八洲科技

如何递归构建带完整路径的嵌套字典结构

日期:2025-12-31 00:00 / 作者:聖光之護

本文介绍如何通过递归函数为嵌套字典中的每个节点添加 folder 字段,其值为从根节点到当前节点的完整路径(如 'kestral/burtree lane/archive'),并修正因重复拼接导致的路径错误。

在处理树形结构数据(如文件系统、组织架构或导航菜单)时,常需为每个节点生成其“全路径”用于展示、路由或存储。给定一个以 children 列表表示子节点的嵌套字典,目标是在不修改原结构的前提下,为每个节点新增 folder 键,其值为由根至该节点的 / 分隔路径

原始代码的问题在于:在递归调用中,既将 data["name"] 拼入了当前层级的 path,又在下一层再次使用 child["name"] 拼接——而 child 的 data["name"] 在子调用中又被重复追加,导致名称重复(如 "Burtree LaneBurtree Lane")。根本原因在于路径计算逻辑与递归参数传递耦合不当。

正确做法是:每层只负责计算“自身路径”,并将该路径(含末尾 /)作为前缀传给子节点,子节点在此基础上追加自己的 name 即可。以下是修复后的专业实现:

def build_structured_dict(data, parent_path=""):
    """
    递归为嵌套字典添加 'folder' 字段,表示从根到当前节点的完整路径。

    Args:
        data (dict): 当前节点字典,必须含 'name' 和 'children' 键
        parent_path (str): 父节点路径(不含当前节点名),默认为空字符串

    Returns:
        dict: 新建的结构化字典,含 'name', 'folder', 'children' 三字段
    """
    # 计算当前节点的完整路径
    current_path = f"{parent_path}{data['name']}" if parent_path else data['name']

    # 构建当前节点字典
    new_dict = {
        "name": data["name"],
        "folder": current_path,
        "children": []
    }

    # 递归处理每个子节点,传入当前路径 + '/' 作为新父路径
    for child in data["children"]:
        new_dict["children"].append(
            build_structured_dict(child, f"{current_path}/")
        )

    return new_dict

关键修正点说明

? 使用示例

a = {
    'name': 'Kestral',
    'children': [
        {
            'name': 'Burtree Lane',
            'children': [
                {'name': 'ARCHIVE', 'children': []},
                {
                    'name': 'Development',
                    'children': [
                        {'name': 'Fee Proposals', 'children': []}
                    ]
                }
            ]
        }
    ]
}

result = build_structured_dict(a)
print(result['folder'])  # 输出: 'Kestral'
print(result['children'][0]['folder'])  # 输出: 'Kestral/Burtree Lane'
print(result['children'][0]['children'][1]['children'][0]['folder'])  # 输出: 'Kestral/Burtree Lane/Development/Fee Proposals'

⚠️ 注意事项

该方案简洁、可读性强,且完全符合函数式递归设计原则:每一层只关注自身状态,路径状态通过参数单向传递,无副作用,易于测试与复用