浅拷贝和深拷贝
- 浅拷贝:
copy.copy()
只拷贝最外层的数据,如list1 = [a, b]
其中a = [1, 2]
,b = [3, 4]
,执行list2 = copy.copy(list1)
时,list2
中只会拷贝了a
,b
的指向,不会在内存区域中创建一份完全一样的数据 - 深拷贝:
copy.deepcopy()
拷贝所有的数据,存入一块新的内存区域中。 - 直接赋值: 在 Python 中称作引用,可以理解为指向
特殊的情形:
- 用
copy.copy()
和copy.deepcopy()
,即深拷贝和浅拷贝,对一个内部全部是不可变类型的数据(如元组中嵌套元组等)进行拷贝,那么他们的结果相同,都是拷贝指向; - 如果对一个拥有可变类型数据的元组进行拷贝,那么
copy.deepcopy()
就是依然是拷贝所有数据,copy.copy()
拷贝的是指向。
对于 list
- 切片操作 是 浅拷贝 等价于
copy.copy()
- 直接复制给另一个变量仅仅是 拷贝指向
# 切片操作举例
In [2]: a = [11, 22]
In [3]: b = [33, 44]
In [4]: c = [a, b]
In [5]: d = c[:]
In [6]: id(c)
Out[6]: 140628676451464
In [7]: id(d)
Out[7]: 140628676526600
In [8]: id(c[0])
Out[8]: 140628686255112
In [9]: id(d[0])
Out[9]: 140628686255112
以上可知,切片操作只拷贝了 list
的最外层,效果和 copy.copy()
一样,为浅拷贝。
对于 numpy
np.copy()
是 深拷贝- 直接赋值给另一个变量依然只是 拷贝指向
# numpy深拷贝示例
In [12]: arr = np.zeros((3,3))
In [13]: arr
Out[13]:
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
In [14]: b = arr.copy()
In [17]: b[0,0] = 1 # 更改b的值
In [18]: arr # arr不变,说明copy()方法是深拷贝
Out[18]:
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
In [19]: b
Out[19]:
array([[ 1., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
# numpy浅拷贝示例
In [33]: b = arr # 直接赋值给变量b
In [34]: b
Out[34]:
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
In [35]: arr[0,0] = 1
In [36]: b
Out[36]:
array([[ 1., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])