2016-11-22 147 views
0

這是一個相當愚蠢的問題,但我真的很困惑。 請看看我的代碼:切片嵌套列表

>>> my_list = [1, 2, 3] 
>>> my_list_new = my_list[:] 
>>> my_list_new[0] = 100 
>>> my_list_new 
[100, 2, 3] 
>>> my_list 
[1, 2, 3] 

因此,它的工作原理應該如此。我複製my_list。當我更改my_list_new - 只更改了一個列表。

現在看這裏:

>>> my_list2 = [[1, 2, 3], [4, 5, 6]] 
>>> my_list_new2 = my_list2[:] 
>>> my_list_new2[0][0] = 100 
>>> my_list_new2 
[[100, 2, 3], [4, 5, 6]] 
>>> my_list2 
[[100, 2, 3], [4, 5, 6]] 

正如你可以看到我改變my_list_new2,但兩個列表改變。它是嵌套列表的正常Python行爲嗎?如何避免它?

+0

下面有兩個很好的答案。要了解更多信息,請點擊此處:https://docs.python.org/2/library/copy.html#module-copy如果列表嵌套,則需要執行'deepcopy',否則只有對嵌套列表的引用是複製。 –

+0

它看起來像你知道你需要使用切片語法來避免只複製引用,所以我不確定爲什麼你感到驚訝,沒有該語法的「複製」列表 - 即內部 - 只被複製引用。 – TigerhawkT3

回答

1

這應該工作打算

my_list_new2 = [list[:] for list in my_list2] 

證明

my_list2 = [[1, 2, 3], [4, 5, 6]] 
my_list_new2 = [list[:] for list in my_list2] 
my_list_new2[0][0] = 100 

my_list_new2 
[[100, 2, 3], [4, 5, 6]] 

my_list2 
[[1, 2, 3], [4, 5, 6]] 
1

名單在Python可變的。含義:

a = [1,2,3] 
b = a 
a[0] = 4 
print(b) 

將打印[4, 2, 3]

所以在嵌套列表僅複製「外」列表中,並修改內部列表的情況下,所以你會修改其他名單。如果你有興趣在此查找表的指針在Python

解決方案:

my_list2 = [[1, 2, 3], [4, 5, 6]] 
my_list_new2 = [inner_lst.copy() for inner_lst in my_list2] # You can use inner_lst[:] as well 
my_list_new2[0][0] = 100 
print(my_list2) 

返回:[[1, 2, 3], [4, 5, 6]]

-1

列表的清單(你的情況l1 = [[1, 2, 3], [4, 5, 6]])包含的對象(名單)。

列表的片爲它插入引用的對象列表中的子集的新淺拷貝。它可以從以下代碼片段中看出。

l1 = [[1, 2, 3], [4, 5, 6]] 
l2 = l1[:] 

print(id(l1))  # 4406414512 
print(id(l2))  # 4382080248 

# Shallow copy, insert references 
print(id(l1[0])) # 4439177768 
print(id(l2[0])) # 4439177768 

要複製的一切,用copy.deepcopy它插入複製對象的。它可以從,

import copy 

l1 = [[1, 2, 3], [4, 5, 6]] 
l2 = copy.deepcopy(l1) 

l2[0][0] = 100 

print(l1) # [[1, 2, 3], [4, 5, 6]] 
print(l2) # [[100, 2, 3], [4, 5, 6]] 
-1

你的外部列表中可以看出my_list2包含引用其他兩個列表。

即使您獨立複製外部列表my_list2,它仍將(最初)包含相同的項目,即對相同的兩個列表具有相同的引用。 (如果您熟悉C/C++,則可以鬆散地將引用到列表視爲指針。)這就是所謂的「淺拷貝」。以下是創建淺拷貝的幾種方法:

my_new_list2 = list(my_list2) 
my_new_list2 = [item for item in my_list2] 
my_new_list2 = my_list2[:] 
import copy; my_new_list2 = copy.copy(my_list2) 

要獲得您想要的行爲,您還需要複製內部列表。您可以像其他人所建議的那樣手動完成此操作,或者您可以讓Python標準庫自動執行此操作。這就是copy.deepcopy是:

import copy 
my_list_new2 = copy.deepcopy(my_list2) 

deepcopy的優點是,它會工作的方式下築巢,不一定只是第一內部級水平的任意數量。