深浅拷贝
深浅拷贝
简单的总结一下Python中的深浅拷贝知识。
浅拷贝: 对于不可变数据类型,浅拷贝后的对象会直接指向被拷贝对象的内存地址。而对于可变数据类型,则只会重新创建一个新的内存空间,但里面的元素的内存地址还是会指向原来对象的内存地址。
例如下面的例子:
import copy a = 3 b = copy.copy(a) a is b Out[5]: True a = 200 b = copy.copy(a) id(a), id(b) Out[9]: (1457813952, 1457813952) a = [1, 2] b = copy.copy(a) id(a), id(b) Out[12]: (2374536578632, 2374536575496) a = [[1], 2] b = copy.copy(a) a[0].append(2) a Out[16]: [[1, 2], 2] b Out[17]: [[1, 2], 2]
上面的例子中,当列表内嵌套列表后,原对象的里面的列表数值改变,拷贝后的列表也跟着改变,而浅拷贝后的列表的地址与原列表不同。

深拷贝: 深拷贝对于不可变对象和浅拷贝一样,都是直接指向原来对象的内存地址,而对于不可变对象,深拷贝后每次都会重新申请内存空间,然后再复制数值大小。
a = 'abc' b = copy.deepcopy(a) id(a), id(b) Out[20]: (2374248427960, 2374248427960) a = [1, [2]] b = copy.deepcopy(a) id(a), id(b) Out[23]: (2374536578696, 2374534310088) a[1].append(3) a Out[25]: [1, [2, 3]] b Out[26]: [1, [2]]
从上面可以看到深拷贝碰到可变对象都是重新申请内存空间的,原可变数据类型的改变对拷贝后对象并没有影响。

接下来列几个浅拷贝的例子 。
1. 这种简写的快速生成列表的方式是浅拷贝
list1 = [[]] * 5 list1[0].append(10) # [[10], [10], [10], [10], [10]] print(list1) list1[1].append(20) # [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]] print(list1) list1.append(30) # [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30] print(list1)
2. 列表的切片也相当于浅拷贝
lst = [[1], [2], [3], [4]] lst2 = lst[1:] print(lst) print(lst2) lst[1].append(2) print(id(lst), id(lst2)) print(lst) print(lst2)
[[1], [2], [3], [4]] [[2], [3], [4]] 2226239378568 2226239378504 [[1], [2, 2], [3], [4]] [[2, 2], [3], [4]]

浙公网安备 33010602011771号