2017-07-12 28 views
0

我試圖實現R-樹數據結構,我有以下RNodeLeaf類:將條目添加到數據結構是重複

class RNodeLeaf(object): 
def __init__(self, entries=[]): 
    self._entries = entries 

def addEntry(self, e): 
    self._entries.append(e) 

,我想一些數據分發到我創建的節點。考慮這段代碼:

 nodes = [] 
     for i in range(8): 

      if i % 4 == 0: 
       node = RNodeLeaf() 
       nodes.append(node) 
      node.addEntry(5) 

     print(nodes) 
     print(nodes[0]._entries) 
     print(nodes[1]._entries) 

所以我的假設是,有創造這是真的,因爲我印print(nodes)和它們都有4個元素2 RNodeLeafs。 但後來我打印print(nodes[x]._entries)我很驚訝,因爲他們都是相同的數據。

[5,5,5,5,5,5,5,5] 

那麼,我錯過了什麼,可以做些什麼來解決這個錯誤?

+2

幾乎可以肯定這:https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument –

+2

並修復它,更改'entries = []'到'entries = None ',並添加'如果條目爲None:entries = []' –

+0

'nodes = []'是問題,但我懶得找到源來標記它是重複的。它會被評估一次,所以它總是一樣的列表。驗證'節點[0] ._條目是節點[1] ._條目' - 它們在內存中是完全相同的對象,而不僅僅是相同的。 –

回答

1

你的問題是你的論點默認爲[]。 閱讀this post表示爲重複。 基本上,定義爲[]__init__行的列表在您的代碼中處處相同。 因此,節點中entries的修改將在每個其他節點的entries屬性中看到。

所以,你需要改變你的__init__來自:

def __init__(self, entries=[]): 
    self._entries = entries 

到:

def __init__(self, entries=None): 
    if entries is None: 
     entries = [] 
    self._entries = entries 

你需要記住:不會讓一個參數默認爲可變對象。

1

我試了一下,得到了同樣的結果。如果調用初始化()這樣一來,它的工作:

node = RNodeLeaf(entries=[]) 

我認爲,這是因爲每個變量是全球性的,公共的,但我不知道。 You can read about default parameters here.當你第一次創建'條目'並且當你創建它時:init()它不會創建一個新對象,它只是獲得一個指向'條目'的指針。所以在node.addEntry(5),它將它添加到'條目'。第二個節點也是這樣,得到一個指向'entries'的指針,這就是爲什麼你有兩個節點具有相同的列表。