2016-03-17 57 views
2

我想打印出一个描述乐队的简单树。我首先创建一个名为“Band”的节点,然后让孩子成为“管乐器”,然后轮流拥有孩子们的“萨克斯管”和“小号”。然后我给一个叫做“Song”的“管乐器”做一个兄弟姐妹等等。该代码是非常简单的:带缩进的打印树

class Node:          
    value = "" 
    down = None 
    right = None 
def write(p): 
    if p==None: 
     return 
    print(p.value) 
    if p.down!=None:  #My idea is that if we go down the tree, we indent first 
     print(" ",end="")  
     write(p.down) 
    write(p.right)  #If we don't go down, we simply write out the siblings 
a=Node() 
a.value="Band" 
a.down=Node() 
a.down.value="Wind instruments" 
a.down.down=Node() 
a.down.down.value="Saxophone" 
a.down.down.right=Node() 
a.down.down.right.value="Trumpet" 
a.down.right=Node() 
a.down.right.value="Song" 
a.down.right.right=Node() 
a.down.right.right.value="String instruments" 
a.down.right.right.down=Node() 
a.down.right.right.down.value="Guitar" 
a.down.right.right.down.right=Node() 
a.down.right.right.down.right.value="Bass" 
write(a) 

输出是:

Band 
    Wind instruments 
    Saxophone 
Trumpet 
Song 
String instruments 
    Guitar 
Bass 

但我想输出是:

Band 
    Wind instruments 
     Saxophone 
     Trumpet 
    Song 
    String instruments 
     Guitar 
     Bass 

人有一个想法如何实现这一目标?

+0

类变量和属性区分!在初始化'Node()''value'后,'down'和'right'对于所有实例都是相同的类变量。通过分配一个值,您将这三个值作为每个实例的单个变量的属性添加。你可以通过'a = Node()来检查它。印刷(一个.__ dict__); a.value = 3;印刷(一个.__字典__)'。对于树木见e。 G。 http://www.openbookproject.net/thinkcs/python/english2e/ch21.html – Chickenmarkus

回答

7

要缩进的打印取决于递归水平,关键是要使用的参数保持你的水平递归时在:

# default with a level of 0, and an indent of 4 characters 
def write(p, depth=0, indent=4): 
    if p==None: 
     return 
    # here we multiply the level by the number of indents 
    # and then you multiply that number with a space character 
    # which will magically show as that number of spaces. 
    print("{}{}".format(" "*(indent*depth), p.value)) 
    if p.down!=None: 
     # then you do not need your print(…, end='') hack 
     # simply increase the depth 
     write(p.down, depth=depth+1, indent=indent) 
    # and for siblings, do not increase the depth 
    write(p.right, depth=depth, indent=indent) 

我使用的是这里的窍门是每默认级别为0,随着深入,您将通过增加参数来增加深度。

然后,当您要打印输出缩进时,您所要做的就是将缩进具有该值的字符串(以及缩进大小),然后您可以根据需要打印缩进:

>>> "A"*42 
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' 

这样的结果:

>>> write(a) 
Band 
    Wind instruments 
     Saxophone 
     Trumpet 
    Song 
    String instruments 
     Guitar 
     Bass 

如果你想让它更窄,因为你有很多的递归:

>>> write(a, indent=1) 
Band 
Wind instruments 
    Saxophone 
    Trumpet 
Song 
String instruments 
    Guitar 
    Bass 

作为奖金,我建议你让write()功能成为你的Node类的一种方法。如果你将其重命名__str__

class Node: 
    value = "" 
    down = None 
    right = None 

    # converts a node into a string 
    def as_str(self, depth=0, indent=4): 
     # building the current node's line, and add it to a list 
     ret = ["{}{}".format(" "*(indent*depth), self.value)] 
     if self.down: 
      # append down recursion first to the list 
      ret.append(self.down.as_str(depth=depth+1, indent=indent)) 
     if self.right: 
      # then append right recursion to the list 
      ret.append(self.right.as_str(depth=depth, indent=indent)) 
     # build the new string, joining each element of the list with a newline 
     return "\n".join(ret) 

    # a handler for printing the list nicely 
    def __str__(self): 
     return self.as_str() 

    def as_repr(self, depth=0, max_depth=2): 
     # building the current node's line, and add it to a list 
     ret = ["'{}'".format(self.value)] 
     if depth > max_depth: 
      ret.append("…") 
     else: 
      if self.down: 
       # append down recursion first to the list 
       ret.append(self.down.as_repr(depth=depth+1, max_depth=max_depth)) 
      if self.right: 
       # then append right recursion to the list 
       ret.append(self.right.as_repr(depth=depth, max_depth=max_depth)) 
      # build the new string, joining each element of the list with a newline 
     return "Node<{}>".format(",".join(ret)) 

    # you might want to also make the repr() nicer 
    def __repr__(self): 
     return self.as_repr() 

而作为一个结果:

>>> a 
Node<'Band',Node<'Wind instruments',Node<'Saxophone',…>,Node<'Song',Node<'String instruments',Node<'Guitar',…>>>>> 
>>> print(a) 
Band 
    Wind instruments 
     Saxophone 
     Trumpet 
    Song 
    String instruments 
     Guitar 
     Bass 

HTH

+0

我不承认这一点: “{} {}”,格式(...) 请问您是否可以详细说明究竟做了什么?否则everthing是明确的! – Lozansky

+0

cf [documentation](https://docs.python.org/3.5/library/string.html#formatstrings)这是处理字符串格式的新的首选方法。最基本的用法是,对于给'format()'的每个参数,它将以相同的顺序替换“{}”标记。它相当于旧式字符串格式:''%s%s“%(”“* indent * level,p.value)''。 – zmo

+0

不打印(“*深度*缩进,p.value)做同样的事情? – Lozansky

0

介绍的输入参数i控制缩进的数量打印出来。

def write(p, i = 1): 
    if p==None: 
     return 
    print(p.value) 
    j = i # store No. of current indent to j 
    if p.down!=None: # process p.down 
     for ii in range(i): 
      print(" ",end="") 
     i += 1   # No. of indent + 1 
     write(p.down, i) 
    if p.right!=None: # process p.right 
     for jj in range(j - 1): 
      print(" ",end="") 
     write(p.right, j) #No. of indent keep same 

运行:

write(a) 

结果:

Band 
    Wind instruments 
     Saxophone 
     Trumpet 
    Song 
    String instruments 
     Guitar 
     Bass