讲一下变量赋值过程: 对于 x = [1,2,3,4] 首先把1,2,3,4这四个对象在内存中依次创建出来,1,2,3,4这都是字值 对于变量x其实就好像c语言中的指针一样,变量实际上是不存储数据的 他只是绑定数据,所以在python文档中成为bound 我们把列表的赋值实际上就是实现列表与数据的绑定我们在del(x)时并不是删除处列表 而是删除的变量x 此时此时列表与变量x没有的绑定关系,python的自带回收机制就会释放列表所占用的内存空间
x = y = [1,2,3,4] 这其实就是创建多个变量绑定了列表, 在列表中其实是有一个引用计数的,用来记录绑定改列表的变量个数,当该计数为0时也就意味着该列表要被回收了
我们再来说说在列表内部机制吧,对于列表的每一个元素都是一个对象,而每一个下标即 x[<index>]就是一个变量然后绑定对应的元素,而我们在改变某一个元素值的时候其实就是该x[<index>]变量绑定另外一个对象 。 然后之前的对象没有了绑定他的变量就会被回收机制释放内存 。 因为x绑定东西实际上是绑定列表每个元素的所有变量的容器,因为元素由变量绑定,所以可以改变。
列表赋值
L1 = [1,2,3,['a','b']]
L2 = L1
L1.append(5)
L2.append(6)
print(L1)
print(L2)
这种方式就是让L1和L2同时绑定同一个对象,也就是说id(L1)和id(L2)的是一样的
浅拷贝
import copy
L1 = [1, 2, 3, ['a', 'b']]
L2 = copy.copy(L1)
L1.append(5)
L1[3].append('cccc')
print(L1)
print(L2)
copy.copy()是浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变,也就是说L2[3]和L1[3]绑定的是同一个对象,可以看下图所示 。
深拷贝
import copy
L1 = [1, 2, 3, ['a', 'b']]
L2 = copy.deepcopy(L1)
L1.append(5)
L1[3].append('ccccc')
print(L1)
print(L2)
深拷贝,包含对象里面的子对象的拷贝,就是说L1[2]和L2[2]绑定的不是同一个对象,所以原始对象的改变不会造成深拷贝里任何子元素的改变