2014-04-18 45 views
3

我正在實現一個圖形結構(僅用於練習目的),現在我來到了兩個我無法向自己解釋的行爲。Python圖形結構和令人驚訝的列表處理

首先,這裏的代碼

class Node: 
    data = None 
    def __init__(self, data): 
     self.data = data 
    def __str__(self): 
     return str(self.data) 
    def __repr__(self): 
     return self.__str__() 

class GraphNode(Node): 
    children = [] 
    def __init__(self, list_of_nodes=None, data=None): 
     if list_of_nodes != None: 
      for node in list_of_nodes: 
       children.add(node) 
     self.data = data 

def createGraphStructure(): 
    node1 = GraphNode(data=1) 
    node2 = GraphNode(data=2) 
    node3 = GraphNode(data=3) 
    node4 = GraphNode(data=4) 
    node5 = GraphNode(data=5) 
    node6 = GraphNode(data=6) 
    node7 = GraphNode(data=7) 
    node8 = GraphNode(data=8) 

    node1.children.append([node2, node3, node4]) 
    node2.children.append([node5, node6, node7]) 
    node4.children.append([node8]) 

    #just a random test/visualization 
    print node1.children 
    #another random printout to test/visualize 
    for n in node1.children: 
     print n.data 

    return node1 

if __name__ == "__main__": 
    root = createGraphStructure() 
    #do stuff with graph, bfs dfs whatever 

現在首先令人吃驚的事情: print node1.childrencreateGraphStructure()會打印出以下幾點:[[2, 3, 4], [5, 6, 7], [8]],但我希望它只是打印出節點1的直接孩子,像[2, 3, 4] 。我在這裏完全無能爲力。

其次,部分

for n in node1.children: 
    print n.data 

拋出以下異常:

File "C:/yeah/you/would/like/to/see/my/path/right?/datastructures.py", line 54, in createGraphStructure 
    print n.data 
AttributeError: 'list' object has no attribute 'data' 

,因爲它似乎,n是一個列表,但是爲什麼呢?不應該從列表中的節點? 我確定有一些明顯的解釋,但我無法弄清楚。另外,因爲我不太熟悉Python,尤其是不是OO。

Thx!

回答

2

首先,當你這樣做:

class GraphNode(Node): 
    children = [] 

children這裏是數據,而不是實例數據。也就是,所有的你的節點共享相同的children對象,所以每個append調用實際上都在改變同一個變量。

要獲取實例數據,您需要在方法中創建children,以便它可以訪問對實例的引用。通常,這是在做__init__

class GraphNode(Node): 
    def __init__(self, list_of_nodes=None, data=None): 
     self.children = [] # <-- initialised here 
     if list_of_nodes != None: 
      for node in list_of_nodes: 
       children.add(node) 
     self.data = data 

的第二個問題是,你使用append它看來,你想用extend

append需要一個對象,並將此對象的列表:

>>> l = [1, 2, 3] 
>>> l.append([4, 5, 6]) 
>>> l 
[1, 2, 3, [4, 5, 6]] 

看到這裏,在列表中的第四個項目是另一個列表。取而代之的是,使用extend,它取一個列表,並將它與它所調用的列表連接起來:

>>> l = [1, 2, 3] 
>>> l.extend([4, 5, 6]) 
>>> l 
[1, 2, 3, 4, 5, 6] 
相關問題