浅拷贝及深拷贝的理解
浅拷贝是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容。
1 | In [1]: import copy |
深拷贝是对于一个对象所有层次的拷贝(递归)
1 | In [45]: a = [1,2,3] |
浅拷贝对不可变类型和可变类型的copy不同
- copy.copy对于可变类型(\列表、字典**),会进行浅拷贝。
- copy.copy对于不可变类型(\元祖、数字、字符串**),不会拷贝,仅仅是指向。
如果c是元祖,那么copy时仅仅是copy元祖的\引用**。
而deepcopy依然是深copy,使用\递归**copy所有
以list为例的实际拷贝情况
如果用=直接赋值,是非拷贝方法。这两个列表是等价的,修改其中任何一个列表都会影响到另一个列表。
浅拷贝的几种方法(对于一维来说是有作用的):
copy()
对于list的第一层,是实现了深拷贝,但对于嵌套的list,仍然是浅拷贝。这其实很好理解,内层的list保存的是地址,复制过去的时候是把地址复制过去了。嵌套的list在内存中指向的还是同一个。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17old = [1,[1,2,3],3]
new = old.copy()
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] =3
print('After:')
print(old)
print(new)
输出:
Before:
[1, [1, 2, 3], 3]
[1, [1, 2, 3], 3]
After:
[1, [3, 2, 3], 3]
[3, [3, 2, 3], 3]使用链表生成式,也是一种浅拷贝
1
2
3
4
5
6
7
8
9
10old = [1,[1,2,3],3]
new = [i for i in old]
print('Before')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After')
print(old)
print(new)使用切片
1
2
3
4
5
6
7
8
9
10old = [1,[1,2,3],3]
new = old[:]
print('Before:')
print(old)
print(new)
new[0] = 3
new[1][0] = 3
print('After:')
print(old)
print(new)
深拷贝:deepcopy()
1 | import copy |
np.array直接复制的话是是深拷贝
1 | a = np.array([[0,1,2], |