Read data from a file and create a tree using anytree in python
Asked Answered
R

1

9

Is there a way to read data from a file and construct a tree using anytree?

Parent Child
A      A1
A      A2
A2     A21

I can do it with static values as follows. However, I want to automate this by reading the data from a file with anytree.

>>> from anytree import Node, RenderTree
>>> A = Node("A")
>>> A1 = Node("A1", parent=A)
>>> A2 = Node("A2", parent=A)
>>> A21 = Node("A21", parent=A2)

Output is

A
├── A1
└── A2
    └── A21
Rousseau answered 17/8, 2018 at 20:9 Comment(0)
G
9

This assumes that the entries are in such an order that a parent node was always introduced as a child of another node beforehand (root excluded).

With that in mind, we can then iterate over the lines, split them (I used split, regex would work too) and create the new nodes.

For how to get a reference to the parent by name, I came up with two solutions:

First, find the parent by name using anytrees find_by_attr

from anytree import Node, RenderTree, find_by_attr

with open('input.txt', 'r') as f:
    lines = f.readlines()[1:]
    root = Node(lines[0].split(" ")[0])

    for line in lines:
        line = line.split(" ")
        Node("".join(line[1:]).strip(), parent=find_by_attr(root, line[0]))

    for pre, _, node in RenderTree(root):
        print("%s%s" % (pre, node.name))

Second, just cache them in a dict while we create them:

from anytree import Node, RenderTree, find_by_attr

with open('input.txt', 'r') as f:
    lines = f.readlines()[1:]
    root = Node(lines[0].split(" ")[0])
    nodes = {}
    nodes[root.name] = root

    for line in lines:
        line = line.split(" ")
        name = "".join(line[1:]).strip()
        nodes[name] = Node(name, parent=nodes[line[0]])

    for pre, _, node in RenderTree(root):
        print("%s%s" % (pre, node.name))

input.txt

Parent Child
A      A1
A      A2
A2     A21

Output:

A
├── A1
└── A2
    └── A21
Ghibelline answered 17/8, 2018 at 21:23 Comment(5)
Hi @Fabian N would you mind adding the input.txt file you are working with? I think your answer could help me but am not sure without seeing the input. What do you mean with "get a reference to the parent by name" ? Anytree has export/import methods, will give you precisely the root node, but just that If you can please provide input.txt, and, also check my question #51904232 thank you very muchHanoi
N Guess you are working directly with the Output as input.txt? There's got to be a simpler way !Hanoi
@Hanoi I just copied the ops example into a file and called it input.txt. You are right, I tried first with anytrees importers but the code to transform the ops input into something one of anytrees importers would understand (json, dict or indent based) turned out to be much longer than simply implementing it directlyGhibelline
Hi Fabian, Can you please help me with this docs.google.com/document/d/… ? I am stuck for more than 4 hours now. ThanksGewgaw
Hey @Fabian N. can you help me with this one? #74622729Stretcherbearer

© 2022 - 2024 — McMap. All rights reserved.