2013-06-26 64 views
0

我真的很奇怪的問題。下面是示例代碼:Python列表追加導致奇怪的結果

class SomeClass(object): 
    a = [] 
    b = [] 
    def __init__(self, *args, **kwargs): 
     self.a = [(1,2), (3,4)] 
     self.b = self.a 
     self.a.append((5,6)) 
     print self.b 

SomeClass() 

打印輸出[(1,2),(3,4),(5,6)],但爲什麼,爲什麼結果不是[(1,2), (3,4)]? 你知道我如何在self.b中擁有self.a的舊值?

謝謝!

+1

原因是b點到,當你改變,你就改變B中也 – matino

回答

6

您正在分配相同的列表self.b,不是副本。

如果你想self.b使用來指代列表的副本,創建一個或者list()或全切片:

self.b = self.a[:] 

self.b = list(self.a) 

您可以輕鬆地從交互式測試這個口譯員:

>>> a = b = [] # two references to the same list 
>>> a 
[] 
>>> a is b 
True 
>>> a.append(42) 
>>> b 
[42] 
>>> b = a[:] # create a copy 
>>> a.append(3.14) 
>>> a 
[42, 3.14] 
>>> b 
[42] 
>>> a is b 
False 
+0

我想補充的第二種方法self.b =名單(自我。 a),請將此添加到答案中。 –

+0

謝謝!解決了! – user232343

1

python中的詞典共享相同的內存s當你將它們分配給彼此時

查找有關此詳細信息請參閱: http://henry.precheur.org/python/copy_list

+2

這些是列表,而不是字典。列表do * not *有一個'.copy()'方法。 –

+0

我的錯誤我將編輯我的答案 – zidsal

2

self.b = self.a不復制列表。它將參考分配給該列表,因此兩個屬性都指向同一個對象。如果您通過一個參考文件修改它,您也會通過另一個參考文件查看更改。

您可以使用copy.copy(the_list)來獲取正確的副本。或者copy.deepcopy(the_list)如果您需要下面的參考資料也進行更新。

+1

列表對象沒有'.copy'方法 – Blender

+0

@Blender我想他的意思是copy.copy(listname) –

+0

是的,抱歉可以更明確。現在編輯。 – viraptor

1

因爲self.aself.b實際上是對同一列表對象的引用。

如果你想修改一個不改變其他,試試這個

 
class SomeClass(object): 
    # a = [] 
    # b = [] # these two class member not necessary in this code 
    def __init__(self, *args, **kwargs): 
     self.a = [(1,2), (3,4)] 
     self.b = list(self.a) # copy to a new list 
     self.a.append((5,6)) 
     print self.b 

SomeClass() 
7

正如許多人已經提到這個問題,最終不得不在相同名單上引用。通過一個引用修改列表只是修改列表列表。

這裏有一個例子,以使事情更清楚,如果需要:

Shared reference

  • 步驟 「A」 是剛過

    self.a = [(1,2), (3,4)] 
    
  • 步驟 「A」 是剛過

    self.b = self.a 
    
  • 步驟「C」是剛過

    self.a.append((5,6)) 
    
+0

你是如何生成這些圖像的? –

+1

@AshwiniChaudhary Inkscape ... –