2011-08-11 74 views
8

我被要求進行編碼測試,但不知道答案。有人有主意嗎?[:] = b和a = b [:]之間的區別? (Python)

+0

可能重複[在Python中列表和列表\ [:\]有什麼區別?](http://stackoverflow.com/questions/4081561/what-is-the-difference-between-list-and -list-in-python) –

+1

@Ignacio:不,這不是重複的 - 該問題沒有提到'a [:] = b'構造。 –

+0

@Adam:甚至沒有開始的部分「分配...時」? –

回答

8

[:]是切片運算符。

當它位於左側時,它會覆蓋列表的內容而不創建新的引用。

當它在右側時,它會創建一個具有相同內容的列表副本。

+0

哦,好吧,現在有道理。爲了澄清,在做一個[:] = b時,id(a)不會改變。 id(a)在執行a = b [:]時發生變化。爲什麼一個人可能比另一個更好? – user701632

+0

是的,你明白了。如果'c'也引用與'a'相同的列表,那麼您可能需要更改內容,以便兩個變量都引用更新後的列表。 – recursive

1

在這兩種情況下,最終列表a是列表b的副本。但用於實現這一點的方法已經改變。

a[:] = b修改列表a,使其具有相同的元素b

a = b[:]產生一個新的列表,它是b副本,並替換列表a

所不同的是,我們是否已經修改現有的列表或創建一個新的列表。

要看到其中的差別:

a = range(3) 
b = range(4) 
c = a # c and a now share the same list 
a[:] = b 
print "a", a 
print "b", b 
print "C", c 

所有三個列表將打印出來的一樣。 C和一個共享相同的對象,所以,當a被修改,以便爲c

a = range(3) 
b = range(4) 
c = a # c and a now share the same list 
a = b[:] 
print "a", a 
print "b", b 
print "C", c 

現在Ç不會打印出相同的。作業後,ac沒有共享同一個對象。

快速,a[:] = b' is probably a little faster then a = b [:]`。第一種形式不必創建新的列表對象,它只能修改現有的列表。其中很大一部分是它可以重新使用列表已經擁有的內存,而不是分配新的內存。

2

a = b[:]呼叫或者在b__getslice____getitem__並將結果a分配。在幾乎所有情況下(例如,列表,元組和其他序列類型),這會生成序列的淺表副本;我不知道任何沒有實現這種行爲的類,但是你可以有一個用戶定義的類型來做一些不同的事情。之前提到舊值a的任何其他對象將繼續引用舊值。

a[:] = b,在另一方面,來電__setslice____setitem__取代的a與那些序列b的元素的子集。在這種情況下,如果a的序列類型表現良好,則將替換整個a,因爲沒有端點的範圍:表示整個序列。這裏的區別是,不可變類型(如元組)不會允許您執行__setslice__(例如通過拋出TypeError異常)。由於底層對象正在被修改,因此之前提到a的任何其他對象也將被更新。

對於可變類型如list,的a = b[:]結果將是相同的a[:] = b,在a將是b淺表副本;對於不可變類型,如tuplea[:] = b無效。對於糟糕的用戶定義類型,所有投注都關閉。其他對象引用a - 與a = b[:]相同,它們指的是原始值(a),但a[:] = b指向修改後的對象(b的淺拷貝)。

相關問題