点击关注我的GitHub

Python中的深拷贝、浅拷贝问题

浅拷贝只是增加了一个指针指向已存在的内存地址,仅仅是指向被复制的内存地址,

如果原地址发生改变,那么浅复制出来的对象也会相应的改变。深拷贝是增加了一个指针并且申请了一个新的内存,

使这个增加的指针指向这个新的内存。

例如:

1 a = [1,2,3,4,['a','b']]
2 b = a #赋值方式
3 c = a[:]#浅拷贝
4 d = copy.copy(a)#浅拷贝
5 e = copy.deepcopy(a)#深拷贝

此时的a,b,c,d,e在显示上是完全相等的,深拷贝获得list的副本,浅拷贝直接用指针指向了a的list。

为使他们显示出区别,对其进行操作:

a.appednd(5)后的显示为:

a = [1, 2, 3, 4, ['a', 'b'], 5]
b = [1, 2, 3, 4, ['a', 'b'], 5]
c = [1, 2, 3, 4, ['a', 'b']]
d = [1, 2, 3, 4, ['a', 'b']]
e = [1, 2, 3, 4, ['a', 'b']]

可以看出,使用赋值b = a后,a模为添加一个新的元素,尽管赋值语句在a改变语句的上面,

b仍然跟随a的添加了一个新的元素。

再来看浅拷贝c,d和深拷贝e,list并不发生改变。

浅拷贝:分配指向a的point的时候,既指定了address同时也获得了当时的len(a),后面的a.append(..)并不改变

原来获得的len,所以浅拷贝不会发生改变。

深拷贝:直接是a的副本,在a发生改变后,原来获得 的副本并不会随之改变

再次进行操作,对list中嵌套的list进行添加值;

a[4].append('c')

1 a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
2 b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
3 c =  [1, 2, 3, 4, ['a', 'b', 'c']]
4 d =  [1, 2, 3, 4, ['a', 'b', 'c']]
5 e =  [1, 2, 3, 4, ['a', 'b']]
6 
7 Process finished with exit code 0

按照先前的分析,a,b变化同步

c,d的浅拷贝len(c)=len(a)=len(b)是不变的,但是在len不变的条件下,对<len内的位置进行了

操作,所以c,d也会改变。

e仍然不变

关于len的取值可看例程:

1 len1 = ['a','b',['a','b']]
2 len2 = ['a','b',['a','b','c']]
3 print(f"{len(len1)}  {len(len2)}")
4 
5 
6 3  3
7 
8 Process finished with exit code 0

 

posted @ 2021-09-29 09:42  justkeen  阅读(95)  评论(0编辑  收藏  举报