2016-10-04 18 views
1

當我操作兩個時,我認爲等效的多維列表,我有不同的結果。列表之間的唯一區別是它們是如何創建的。我正在使用Python 3.4.3在等效多維列表上操作時的不同行爲

>>> b = [[1,2],[1,2]] 
>>> b[0][0] += 1 
>>> b 
[[2, 2], [1, 2]] 
>>> b = [[1,2]] * 2 
>>> b 
[[1, 2], [1, 2]] 
>>> b[0][0] += 1 
>>> b 
[[2, 2], [2, 2]] 

正如你所看到的,b和它們的操作是相同的,但結果不是。我猜測這與它們的創建方式有關,因爲這是唯一的區別,但我不明白。

它與Python相同2.7.6

>>> b = [[1,2],[1,2]] 
>>> b 
[[1, 2], [1, 2]] 
>>> c = [[1,2]] * 2 
>>> c 
[[1, 2], [1, 2]] 
>>> c == b 
True 
>>> b[0][0] += 1 
>>> b 
[[2, 2], [1, 2]] 
>>> c[0][0] += 1 
>>> c 
[[2, 2], [2, 2]] 
>>> c == b 
False 
>>> 
+0

'[[1,2]] * 2'爲2個拷貝,但'[1,2]' –

+0

'[「test」] * 3'的1個引用僅僅是'[「test」的快捷方式, 「測試」,「測試」]。這不像第一種情況那樣是一種手術。這就是爲什麼它也適用於字符串。 – imant

回答

1
b = [[1,2],[1,2]] 

print(id(b[0])) # 139948012160968 
print(id(b[1])) # 139948011731400 

b = [[1,2]]*2 

print(id(b[0])) # 139948012161032 
print(id(b[1])) # 139948012161032 

`id() shows the object's ID or the memory location in Python.

當你做你b = [[1,2]]*2基本上是說咱們都指向同一個對象兩次並將其存儲在A中的B名單。

當你做b = [[1,2],[1,2]]你基本上說讓我得到兩個不同的對象,並把它們放在一個列表中,讓b引用列表。

因此對於後面的例子,當然你會得到那個輸出,因爲它們是你改變的同一個對象。你可以把它看作是我給你同一個房子的地址,我有我給你的同一個地址。我們在同一個地方結束,我們對房子做了什麼改變,我們一起看到它。

修改意見:

正確!他們正在改變內存的處理方式,但其值相同。

==測試值是否相同。 is測試對象是否相同。所以在我們的例子:

#First case: 
print(b[0] == b[1]) #true 
print(b[0] is b[1]) #false 

#second case: 
print(b[0] == b[1]) #true 
print(b[0] is b[1]) #true 

編輯的第二條意見第二次〜

import copy 
x = [1,2] 
b = [copy.copy(x) for i in range(3)] 
print(id(b[0])) #140133864442248 
print(id(b[1])) #140133864586120 
print(id(b[2])) #140133864568008 
print(b) #[[1, 2], [1, 2], [1, 2]] you can extend range to 256. 

如果你想要一個獨特的目標,並希望將其與另一對象複製,請嘗試使用copy。它會創建一個具有相同值的新對象。

編輯再次使用我最喜歡的功能sum之一:

這或多或少是多餘的,它可能會迷惑你多一些,但也sum工作過。

x = [1,2] 
b = [sum([x],[]) for i in range(3)] 
print(id(b[0])) #140692560200008 
print(id(b[1])) #140692559012744 
print(b) #[[1, 2], [1, 2], [1, 2]] 

將在對象中返回不同的實例。我只指出這是爲了防止你不想導入任何東西或導入任何東西。

+0

謝謝!所以列表是等價的,但不是數據如何在內存中處理? 我特別指的是第二段代碼,它說 b == c 真 – Piepongwong

+0

所以我如何得到256個[1,2]和不同引用的列表? – Piepongwong

+0

正確!看到第一個問題和第二個評論的編輯答案!希望它是有道理的。 – MooingRawr

0

這是在Python中很好理解的行爲。

a = [[], []] # two separate references to two separate lists 
b = [] * 2 # two references to the same list object 
a[0].append(1) # does not affect a[1] 
b[0].append(1) # affects b[0] and b[1] 
0

在第二種情況下,您正在製作所謂的[1,2]列表的淺表副本。實際上,這意味着你在內存中的某個地方有你的名單[1,2],而當你寫[[1,2]]*2時,你說你需要兩個引用到同一個列表。因此,當您更改其中一個列表時,您實際上正在更改b中的兩個項目都指向的列表。