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

Python如何获取树结构中所有可能路径组成的嵌套列表

原有代码问题分析

你当前的实现无法生成正确路径,核心原因有3点:

  • 所有节点都追加到同一个共享列表中,没有区分不同分支的独立路径,最终只会得到平铺的节点集合
  • 缺少回溯逻辑:遍历完某个子分支后,没有清除当前分支的节点状态,导致不同分支的节点会混杂在同一条路径中
  • 没有在路径终点(叶子节点)保存当前路径的独立副本,递归过程中的列表修改会影响已经存入结果的路径
正确实现方案

采用深度优先遍历+回溯的思路实现:维护一个临时列表存储当前遍历路径,每进入一个节点就将其加入路径,遍历完该节点所有子节点后将其移出路径(回溯),遇到叶子节点时将当前路径的副本存入最终结果。

适配CategoryPath类型的实现

返回List[List[CategoryPath]]格式的结果,匹配你现有代码的类型定义:

from typing import List

# 若你的项目中已经定义过这两个类可以直接忽略,这里仅作类型示意
class CategoriesTreeNodeFull:
    def __init__(self, id: int, name: str, children: List['CategoriesTreeNodeFull']):
        self.id = id
        self.name = name
        self.children = children

class CategoryPath:
    def __init__(self, id: int, name: str):
        self.id = id
        self.name = name


def create_category_paths_from_children(root_nodes: List[CategoriesTreeNodeFull]) -> List[List[CategoryPath]]:
    result = []

    def dfs(current_node: CategoriesTreeNodeFull, current_path: List[CategoryPath]):
        # 将当前节点加入路径
        current_path.append(CategoryPath(name=current_node.name, id=current_node.id))
        
        if not current_node.children:
            # 到达叶子节点,存入当前路径的副本(必须存副本,否则后续回溯会修改已存入的结果)
            result.append(current_path.copy())
        else:
            # 递归遍历所有子节点
            for child in current_node.children:
                dfs(child, current_path)
        
        # 回溯:移除当前节点,切换到其他分支
        current_path.pop()

    # 遍历所有根节点启动递归
    for root in root_nodes:
        dfs(root, [])
    
    return result

直接返回ID嵌套列表的实现

如果需要直接得到你给出的纯ID嵌套列表格式(如[[24,137,237], ...]),可以用更简洁的版本:

def create_category_id_paths(root_nodes: List[CategoriesTreeNodeFull]) -> List[List[int]]:
    result = []

    def dfs(current_node: CategoriesTreeNodeFull, current_path: List[int]):
        current_path.append(current_node.id)
        if not current_node.children:
            result.append(current_path.copy())
        else:
            for child in current_node.children:
                dfs(child, current_path)
        current_path.pop()

    for root in root_nodes:
        dfs(root, [])
    return result
注意事项

你给出的原始输入结构中,id=154的节点和id=155的节点是平级关系,这种情况下输出的路径会包含[24,151,154],不会出现[24,151,155,154]。如果要得到你期望输出中的[24,151,155,154],需要将id=154的节点移动到id=155节点的children列表中,调整后运行代码即可得到和期望完全一致的结果。

调用测试示例

# 工具函数:将字典格式的树数据转换为节点对象
def build_tree(raw_data: list) -> List[CategoriesTreeNodeFull]:
    node_list = []
    for item in raw_data:
        children = build_tree(item.get("children", []))
        # name字段可替换为你实际数据中的name值
        node_list.append(CategoriesTreeNodeFull(id=item["id"], name=str(item["id"]), children=children))
    return node_list

# 调整后的数据(154放到155的children下,匹配你的期望输出)
raw_tree = [
    {
        "id": 24,
        "children": [
            {
                "id": 137,
                "children": [{"id":237,"children":[]}, {"id":251,"children":[]}]
            },
            {
                "id": 151,
                "children": [
                    {"id":155, "children":[{"id":154,"children":[]}]}
                ]
            }
        ]
    }
]

root_nodes = build_tree(raw_tree)
# 打印ID路径结果
print(create_category_id_paths(root_nodes))
# 输出:[[24, 137, 237], [24, 137, 251], [24, 151, 155], [24, 151, 155, 154]]

内容的提问来源于stack exchange,提问作者Daniel Gašparík

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:45:47