Python 3.7中浅拷贝引发的二维列表修改异常问题咨询
为什么修改B的内层元素会影响A?浅拷贝 vs 深拷贝的经典陷阱
这问题其实是Python里浅拷贝和深拷贝的常见坑,我来给你把逻辑掰扯清楚~
首先你得明白:A[:][:]根本不是你以为的“完全复制整个二维列表”,它只是做了两层浅拷贝,但内层的子列表依然和原列表A共享内存引用。
先拆解A[:][:]到底干了什么
- 第一步
A[:]:对外层列表做一次浅拷贝,生成一个新的外层列表,但这个新列表里的元素(也就是[1,2]和[0,3]这两个子列表),其实只是复制了“指向原列表子列表的指针”,并没有把子列表本身复制一份——它们和A里的子列表是内存里的同一个对象。 - 第二步再对这个新列表做
[:]:本质上是再复制一次外层列表,得到另一个新的外层列表,但里面的子列表引用依然没变化,还是和A里的子列表完全共享。
所以最终,B和A的外层列表是不同的独立对象,但它们包含的子列表是完全相同的对象(内存地址一致)。
两种操作的差异原因
情况1:
del B[0]
你删除的是B这个外层列表的第一个元素(也就是那个指向[1,2]的引用),但A的外层列表里的引用还完好无损,所以A的内容完全不受影响——这就是你觉得符合预期的原因。情况2:
del B[0][1]
你操作的是B[0]这个子列表,而B[0]和A[0]是内存里的同一个列表对象!你删除这个子列表的第二个元素,相当于直接修改了这个共享的对象,所以A里对应的子列表自然也会跟着变——因为它们本来就是同一个东西啊。
怎么创建完全独立的副本?
如果你想让B和A彻底无关,修改B的任何部分都不影响A,就得用深拷贝:
import copy A = [[1,2],[0,3]] B = copy.deepcopy(A) # 真正的完全复制,内层外层都独立 del B[0][1] print(A) # 输出 [[1,2],[0,3]],完全不受影响 print(B) # 输出 [[1], [0,3]]
如果是简单的二维列表,也可以手动实现深拷贝,不用导入模块:
A = [[1,2],[0,3]] B = [row[:] for row in A] # 对每个子列表也做浅拷贝,实现二维的独立复制 del B[0][1] print(A) # 依然是 [[1,2],[0,3]]
内容的提问来源于stack exchange,提问作者EinderJam
相关产品推荐
相关产品推荐

