2015-06-17 31 views
8

Mam następujące klasy, która reprezentuje węzeł drzewa:Jak wydrukować drzewo w Pythonie?

class Node: 
    def __init__(self, name, parent=None): 
     self.name = name 
     self.parent = parent 
     self.children = [] 
     # ... 

     if parent: 
      self.parent.children.append(self) 

Jak drukować takie drzewo?

Odpowiedz

11

To jest moje rozwiązanie:

def print_tree(current_node, indent="", last='updown'): 

    nb_children = lambda node: sum(nb_children(child) for child in node.children) + 1 
    size_branch = {child: nb_children(child) for child in current_node.children} 

    """ Creation of balanced lists for "up" branch and "down" branch. """ 
    up = sorted(current_node.children, key=lambda node: nb_children(node)) 
    down = [] 
    while up and sum(size_branch[node] for node in down) < sum(size_branch[node] for node in up): 
     down.append(up.pop()) 

    """ Printing of "up" branch. """ 
    for child in up:  
     next_last = 'up' if up.index(child) is 0 else '' 
     next_indent = '{0}{1}{2}'.format(indent, ' ' if 'up' in last else '│', " " * len(current_node.name)) 
     print_tree(child, indent=next_indent, last=next_last) 

    """ Printing of current node. """ 
    if last == 'up': start_shape = '┌' 
    elif last == 'down': start_shape = '└' 
    elif last == 'updown': start_shape = ' ' 
    else: start_shape = '├' 

    if up: end_shape = '┤' 
    elif down: end_shape = '┐' 
    else: end_shape = '' 

    print '{0}{1}{2}{3}'.format(indent, start_shape, current_node.name, end_shape) 

    """ Printing of "down" branch. """ 
    for child in down: 
     next_last = 'down' if down.index(child) is len(down) - 1 else '' 
     next_indent = '{0}{1}{2}'.format(indent, ' ' if 'down' in last else '│', " " * len(current_node.name)) 
     print_tree(child, indent=next_indent, last=next_last) 

Przykład zastosowania:

shame = Node("shame") 

conscience = Node("conscience", shame) 
selfdisgust = Node("selfdisgust", shame) 
embarrassment = Node("embarrassment", shame) 

selfconsciousness = Node("selfconsciousness", embarrassment) 
shamefacedness = Node("shamefacedness", embarrassment) 
chagrin = Node("chagrin", embarrassment) 
discomfiture = Node("discomfiture", embarrassment) 
abashment = Node("abashment", embarrassment) 
confusion = Node("confusion", embarrassment) 

print_tree(shame) 

I to jest wyjście:

 ┌conscience 
    ├self-disgust 
shame┤ 
    │    ┌self-consciousness 
    │    ├shamefacedness 
    │    ├chagrin 
    └embarrassment┤ 
        ├discomfiture 
        ├abashment 
        └confusion 

UPDATE:

Pchnąłem a more complete solution na PyPi.

+0

Świetnie! Znalazłeś to sam. –

+3

Twoje drzewo potrzebuje zwiększenia samooceny :) – CoryKramer

+0

Po prostu dzielę się poranną pracą [jak zachęca StackOverflow] (http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer -Twoje-własne-pytania /) :) – clemtoy