为何修改原列表内部元素会影响副本,替换整个元素则不会?
Python嵌套列表浅拷贝的行为解析
先明确:你用b = list(a)做的是浅拷贝,不是深拷贝,这是理解后续现象的核心。
1. 修改a[0] = [9,10]的过程与现象原因
执行a = [[0,1],[2,3]]时,内存中会创建两个独立的子列表对象[0,1]和[2,3],外层列表a存储的是指向这两个子列表的引用。
执行b = list(a)后,会生成一个新的外层列表b,但b的元素和a的元素完全一样——都是指向那两个子列表的引用。简单说,a和b是两个独立的“外层容器”,但容器里装的是同一个“子容器”。
当你执行a[0] = [9,10]时,这是给a的第一个位置替换了一个全新的子列表。此时a的第一个元素不再指向原来的[0,1],转而指向新创建的[9,10]。但b的第一个元素依然指向原来的[0,1],所以b的内容不会发生变化。
2. 修改a[1][0] = 11的现象原因
执行a[1][0] = 11时,你并没有替换a[1]指向的子列表,而是直接修改了这个子列表内部的元素值。因为a[1]和b[1]指向的是同一个子列表对象,这个对象的内容被修改后,所有指向它的引用(包括a[1]和b[1])都会同步看到变化,所以b的第二个子列表也会变成[11,3]。
完整代码示例
>>> a=[[0,1],[2,3]] >>> b=list(a) >>> a [[0, 1], [2, 3]] >>> b [[0, 1], [2, 3]] >>> a[0]=[9,10] >>> a [[9, 10], [2, 3]] >>> b [[0, 1], [2, 3]] >>> a[1][0]=11 >>> a [[9, 10], [11, 3]] >>> b [[0, 1], [11, 3]]
内容的提问来源于stack exchange,提问作者Hamed
相关产品推荐
相关产品推荐

