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

如何基于已有anytree树构建新的Python anytree树?

基于anytree构建新树(不修改原树)

原树定义与结构

以下是原树的代码文件mytree.py:

# mytree.py
import anytree as at
import anytree.importer


data = {
    "a": "root",
    "children": [
        {
            "a": "sub0",
            "b": 3,
            "children": [{"a": "sub0A", "b": 9}, {"a": "sub0B", "b": 1}],
        },
        {"a": "sub1", "b": 5},
    ],
}
root = at.importer.DictImporter().import_(data)

执行命令进入交互模式:

python3 -i mytree.py

打印原树结构:

print(at.RenderTree(root, style=at.render.ContStyle()))
# 输出:
AnyNode(a='root')
├── AnyNode(a='sub0', b=3)
│   ├── AnyNode(a='sub0A', b=9)
│   └── AnyNode(a='sub0B', b=1)
└── AnyNode(a='sub1', b=5)

需求说明

需要构建一个与原树结构完全一致的新树,要求:

  • 新节点不含原树的b属性
  • 新增c属性:原节点b值小于6时c为"small",大于等于6时为"large"
  • 全程不修改原树

尝试的遍历方式(未成功)

用户尝试用层序分组遍历,但未完成实现:

for on_this_level in at.LevelOrderGroupIter(root)

解决方案

方法1:递归遍历构建

递归遍历原树的每个节点,逐个创建新节点并设置对应属性,同时关联子节点:

import anytree as at

def build_new_tree(original_node):
    # 计算c属性值(根节点没有b属性,默认设为small)
    c_val = "large" if hasattr(original_node, 'b') and original_node.b >= 6 else "small"
    # 创建新节点,仅保留a属性和新增c属性
    new_node = at.AnyNode(a=original_node.a, c=c_val)
    # 递归处理子节点,将子节点的父节点设为当前新节点
    for child in original_node.children:
        build_new_tree(child).parent = new_node
    return new_node

# 生成新树
new_root = build_new_tree(root)

# 验证新树结构
print(at.RenderTree(new_root, style=at.render.ContStyle()))

方法2:迭代式层序遍历构建

如果偏好迭代方式,可以用层序遍历(LevelOrderIter),同时维护原节点到新节点的映射,确保子节点能正确关联父节点:

import anytree as at

# 用字典存储原节点到新节点的映射,方便快速查找父节点
node_mapping = {}

# 层序遍历原树的所有节点
for original_node in at.LevelOrderIter(root):
    # 计算c属性值
    c_val = "large" if hasattr(original_node, 'b') and original_node.b >= 6 else "small"
    # 创建新节点
    new_node = at.AnyNode(a=original_node.a, c=c_val)
    node_mapping[original_node] = new_node
    
    # 根节点没有父节点,非根节点需要关联对应的父节点
    if original_node.parent is not None:
        new_node.parent = node_mapping[original_node.parent]

# 获取新树的根节点
new_root = node_mapping[root]

# 验证新树结构
print(at.RenderTree(new_root, style=at.render.ContStyle()))

以上两种方式都不会对原树做任何修改,而是完全新建一个符合要求的树结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:56:13