1

Currently I have data in the following format

A
A -> B -> C -> D -> Z
A -> B -> O
A -> X

This is stored in a list [line1,line2, and so forth]

Now I want to print this in the following manner

 A
 |- X
 |- B
    |- O
    |- C
       |- D
          |- Z

I'm new to python so. I was thinking of finding '->' in each element in array and replacing with space. I don't know to go forward.

4
  • by "this is stored in a list" -- Can you actually give a concrete example of the list? is it ['A', 'A -> B -> C -> D -> Z', 'A -> B -> O', 'A -> X']? Commented Dec 4, 2013 at 21:53
  • what if Z went back to A just for the sake of argument ... Commented Dec 4, 2013 at 21:55
  • 1
    @JoranBeasley -- Then you wouldn't have a tree -- Wouldn't that be a graph? Commented Dec 4, 2013 at 21:57
  • @mgilson thanks :P you are correct. JennCole are you just trying to get a graphical representation of it? or are you trying to just have an internal representation of it? is this for homework or are you trying to solve a RL problem? Commented Dec 4, 2013 at 21:59

2 Answers 2

1

Here is a little code to get you started (add your own beautifications as needed):

>>> def make_links(data):
        'Create a dictionary mapping nodes to a set of their successors'
        links = {}
        for row in data:
            nodes = row.replace(' ', '').split('->')
            for a, b in zip(nodes[:-1], nodes[1:]):
                links.setdefault(a, set()).add(b)
        return links

>>> def draw_tree(links, start, depth=0):
        'Recursively print a tree from a given starting point and given depth'
        print('   ' * depth + start)
        for node in sorted(links.get(start, [])):
            draw_tree(links, node, depth+1)

>>> data = ['A', 'A -> B -> C -> D -> Z', 'A -> B -> O', 'A -> X']

>>> links = make_links(data)
>>> links
{'A': {'X', 'B'}, 'C': {'D'}, 'B': {'C', 'O'}, 'D': {'Z'}}

>>> draw_tree(links, start='A')
A
   B
      C
         D
            Z
      O
   X
Sign up to request clarification or add additional context in comments.

Comments

1

First we parse the string:

data = """A
    A -> B -> C -> D -> Z
    A -> B -> O
    A -> X
    """

lines = [x.split(' -> ') for x in data.split('\n') if x]

This will return

[['A'], ['A', 'B', 'C', 'D', 'Z'], ['A', 'B', 'O'], ['A', 'X']]

Then we build it:

def addone(owner, data):
    o = owner.setdefault(data.pop(0), {})
    if data:
        addone(o, data)

root = {}
for line in lines:
    addone(root, line)

Now the root will be:

{'A': {'X': {}, 'B': {'C': {'D': {'Z': {}}}, 'O': {}}}}

Finally we display it:

def show(base, data):
    while data:
        k, v = data.pop(0)
        print '%s|-%s' % (base, k)
        if v:
            if data:
                show(base + '| ', v.items())
            else:
                show(base + '  ', v.items())

show("", root.items())

It will output on my place like this:

|-A
  |-X
  |-B
    |-C
    | |-D
    |   |-Z
    |-O

O and C has different order, because python dict not remember order, which is easy to change by sort or use collections.OrderedDict

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.