这是一个非常愚蠢的问题,但我真的很困惑。 请看看我的代码:
>>> 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 :(得分: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 :(得分: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]]
答案 2 :(得分:-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]]
答案 3 :(得分:-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
的优势在于它可以在任意数量的嵌套级别下工作,而不一定只是第一个内部级别。