Python学习笔记——深拷贝与浅拷贝

浅拷贝

这里写图片描述

解读:

开辟空间存放[11,22,33],然后将其地址放在a中,执行b = a后,将[11,22,33]的地址也放在b中。这样就完成了浅拷贝。

浅拷贝,拷贝后两者is和==都为true

并且无论是a变了还是b变了,只要是不涉及开辟新空间的情况下,都直接影响另一个变量,使得a和b的is和==返回值都为true。

深拷贝

这里写图片描述

这里可以看到深拷贝的命令需要import copy,然后调用copy.deepcopy()(真·深拷贝)

程序解读:

开辟空间A存放[11,22,33],然后将其地址放在a中,在执行b = copy.deepcopy(a)后,py君又开辟了新空间B,直接将原来A空间里的[11,22,33]拿了过来放到B空间中,然后把B控件的地址给了b。这样就完成了深拷贝。

深拷贝后,两者 == 为真,is为假,数据更新互不影响。

拓展

帮助理解浅拷贝与深拷贝:
请看如下代码

这里写图片描述

d 是 c 的浅拷贝
e 是 c 的深拷贝
f 是 c 的拷贝


经过刚才的讲解,d应该已经不用讲了,与c完全相同。


我们来看深拷贝的e
我们更改a.append(4)
看深拷贝的e怎么变?

这里写图片描述

就像刚才说的,深拷贝后,c与e的数据完全独立,不会互相影响。

稍微解读下,

这里写图片描述

在执行e = copy.deepcopy(c)时,py君看见c中放的是地址,又发现此地址里对应的空间中存放着不是不可变类型的数据,就开辟一个新空间X将c中的数据拿过来放到空间X中,正要拿的时候,发现c中存放着两个地址,这时候py君就有开辟了一个新空间Y,去c中第一个地址里去拿数据放在空间Y中,然后把空间Y的地址存放在了空间X中,然后又开辟了新空间Z将c中第二个地址里去拿数据存放在空间Z中,之后把空间Z的地址放到了空间X中,最后,将空间X的地址给e。到此结束此操作。

这一些列操作,其实就是递归,如果遇见不是数据而是地址了,就在调用一次自己。
就像上面所说的,e = copy.deepcopy(c),因为c是列表长度是2
就可以理解为e[0] = copy.deepcopy(c[0])和e[1] = copy.deepcopy(c[1])的集合。
(其实是e[0] = copy.copy(c[0])和e[1] = copy.copy(c[1]))


下面是拷贝的f
用同样的方法,改变a.append(4)

结果发现:

这里写图片描述

这里写图片描述

py君,你在逗我,这什么鬼?

这其实就是copy.copy方法。

我们来画个图:

这里写图片描述

看完这个图,会不会有一点点明白了?
我再稍微解释下我的理解:

f = copy.copy(c),py君一看c里放着是地址,看地址指向的空间中里存放着是不是不可变类型,一看存放的也是地址,直接开辟新空间X,然后将c指向的控件里的东西全部移动到空间X中,然后把空间X地址放在f中。操作完毕。

拷贝操作,看见地址a,直接开辟也仅开辟一次空间X。不管是地址a所对应的空间中是地址还是数据直接放入空间X。

我就怕我越解释越晕。TAT


总结

浅拷贝、拷贝、深拷贝

浅拷贝 a = b 在不涉及开辟新空间的情况下,数据完全同步。

拷贝 a = copy.copy(b) 遇见一次地址,开辟且仅开辟一次新空间,将此地址中的数据/地址直接放入新空间中,新空间的地址放入新变量中。

深拷贝 a = copy.deepcopy(b) 只要遇见一次地址,就开辟一次新空间(无次数限制),本质上就是拷贝方法的递归。

当然如果在用拷贝方法的时候,被拷贝对象存放的地址所对应的空间中是不可变类型。那就自动变成浅拷贝。不可变类型:string,integer,tuple

以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值