0

我正在使用anytree从文件中生成树,Tree.txt. 每个缩进为 3 个空格 ( )。这是我的文件的样子:

ROOT
   Node1
      Node2
         Node3
            Node4
   Node5
   Node6

这是我到目前为止生成代码的内容:

from anytree import Node, RenderTree, find_by_attr

def parse_tree():
    with open('Tree.txt', 'r') as file:
        file_contents = file.readlines()
        root = Node("ROOT")

        current_indent = -1 # store index for comparing later
        for (index, line) in enumerate(file_contents):

            leading_spaces = len(line) - len(line.lstrip(' '))
            indent = int(leading_spaces / 3) # indent = 3 spaces
            
            if indent > current_indent: # node must be 1 level down
                
                # get the previous Node (1 level up)
                previous_line = file_contents[index - 1].strip()
                current_line = line.strip()
                parent = find_by_attr(root, previous_line)
                Node(current_line, parent=parent) # start searching from top node (root) for `previous_line`
                current_indent = indent
            else: # node is on same level or higher
                print(f"What to do for {line.strip()}?") 
                # what should I do here?

        print(RenderTree(root)) # print the output

parse_tree()

但是,这会打印出来:

What to do for Node5?
What to do for Node6?
Node('/ROOT')
└── Node('/ROOT/Node1')
    └── Node('/ROOT/Node1/Node2')
        └── Node('/ROOT/Node1/Node2/Node3')
            └── Node('/ROOT/Node1/Node2/Node3/Node4')

生成的树很好,但直到Node4-Node5并且Node6丢失了。这是意料之中的,因为我没有处理当前缩进小于前一个缩进的情况(请参阅 参考资料# what should I do here?)。

当前缩进小于上一个缩进怎么办?我知道我需要n更上一层楼,但我怎么知道那是哪一层呢?

4

1 回答 1

1

您需要一种堆栈来跟踪节点的深度,然后您可以使用初始空间的数量来确定将每个叶子附加到哪个父节点。例如,三个空格表示向下一层,因此您需要附加到堆栈中索引 0 处的根节点。(您也可以说通过使用堆栈我们正在获取叶子的绝对深度,而如果我有任何意义,您尝试相对解决它)。我怀疑如果你使用find_by_attr,如果有同名的叶子,那可能不起作用。

treestring = '''
ROOT
   Node1
      Node2
         Node3
            Node4
   Node5
   Node6'''.strip()

leaves = treestring.splitlines()

# initialize stack with the root node
stack = {0: Node(leaves.pop(0))}

for leaf in leaves:
    
    # determine the node's depth
    leading_spaces = len(leaf)-len(leaf.lstrip(' '))
    level = int(leading_spaces/3)
    
    # add the node to the stack, set as parent the node that's one level up
    stack[level] = Node(leaf.strip(), parent=stack[level-1])

tree = stack[0]

for pre, _, node in RenderTree(tree):
    print(f"{pre}{node.name}")

结果:

ROOT
├── Node1
│   └── Node2
│       └── Node3
│           └── Node4
├── Node5
└── Node6
于 2021-07-10T21:25:51.780 回答