Python列表拷贝疑问:为何修改B的嵌套元素会影响原列表A?
为什么修改B的子列表会影响A?这是浅拷贝的锅!
这绝对是Python新手最容易踩的坑之一,我来给你掰扯明白到底咋回事~
先看你贴的代码执行过程:
>> A = [1,[2,3],4] >> B = A[:] >> B[0] = 'x' >> B
['x',[2,3],4]
A
[1,[2,3],4]
B[1][0] = 'y'
B
['x',['y',3],4]
A
[1,['y',3],4]
你以为B = A[:]会创建一个完全独立的A的拷贝,但结果却不是——问题出在切片[:]做的是浅拷贝(shallow copy),不是深拷贝!
浅拷贝到底拷贝了啥?
- 对于列表里的不可变元素(比如整数、字符串、元组这些不能修改的对象),浅拷贝会给B创建新的元素引用,所以你修改
B[0] = 'x'时,只是改了B自己的第一个元素,A的第一个元素还是原来的1,这部分符合你的预期。 - 但对于列表里的可变元素(比如另一个列表、字典这些能修改的对象),浅拷贝只复制了这个元素的内存引用,而不是把整个可变对象复制一份。也就是说,
A[1]和B[1]指向的是内存里同一个[2,3]列表!
所以当你执行B[1][0] = 'y'时,你其实是在修改那个A和B共享的子列表,A自然也会看到这个变化。
怎么解决?用深拷贝!
如果你想要让B成为A完全独立的拷贝,不管嵌套多少层可变元素都互不影响,就得用Python标准库的copy.deepcopy():
import copy A = [1,[2,3],4] B = copy.deepcopy(A) B[1][0] = 'y' print(A) # 输出:[1, [2, 3], 4],完全不受B的修改影响
这样不管A里嵌套多少层可变对象,deepcopy都会递归地把所有元素都复制一份,彻底切断和原列表的关联~
内容的提问来源于stack exchange,提问作者E.Praneeth
相关产品推荐
相关产品推荐

