2016-03-17 59 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