列表复制
如下分别是三种复制, =
,切片(Shallow Copy)和deepcopy
。
1 | from copy import deepcopy |
首先,这三种复制有共同点:
x==y==z==u
返回True
,它们的值都是一样的。
对于第一种=
,
因为列表是mutable对象,这里的y和x将指向同一个地址。
x is y
返回True
,表明它们是同一个object,只是两个names。
对于第二种和第三种,`z is x or u is x
返回False
。
它们已经和原来的x
不是同一个对象了,只是它们的values是相等的。
重点来了,
1 | 0] = 4 x[ |
可以看见,当我们改变了x
的第一个列表元素为整数4
,第二个列表元素的第一个元素为5
。
y
和x
保持一致,因为它们本身就是同一个object。
z
是切片复制,浅复制。这个深浅是什么意思呢?x
本身是个两层嵌套的列表。而浅复制z = x[:]
就是指,建立一个和x
等长的列表z
,z
中每个元素按照顺序指向x
中元素对应的地址。此时,x
的第一个元素从指向一个列表为[0, 1]
的地址变成指向整数4
的地址。而x
第二个元素的地址没有改变,改变的是x
第二个元素中第一个元素的指向,从指向整数2
变成指向整数5
。我们可以使用验证它们第二个元素在内存中的地址是不是一样的。
1 | 1]) == id(z[1]) id(x[ |
而深复制u = deepcopy(x)
就好理解了,创建一个新的对象,递归地对x
中元素进行复制,并重新分配内存地址。所以u
和x
已经是完全没有关联的对象。
待验证的个人说法,
y = x
是把建立变量名称y
到x
内存地址的映射。
z = x[:]
是建立变量名称z
到某列表的映射,该列表元素的内存地址与x
元素的相等。
u = deepcopy(x)
是建立变量名称u
到某列表的映射,该列表元素的内存地址与x
元素的无关。