深浅拷贝

深浅拷贝

简单的总结一下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]]

 

posted @ 2019-07-19 21:25  yscl  阅读(97)  评论(0)    收藏  举报