Python赋值与深浅拷贝问题

        第一步:重点理解可变对象与不可变对象的概念本质改变值是否会开辟新的id地址问题,也就是指针指向对象是否会更改;

赋值语句:

a = 'python'

        第二步:赋值、浅拷贝、深拷贝三者之间的区别:
        赋值:就是复制了所有引用,相当于给源对象起别名。

例如,a = 'python',b = a,给'python'起别名b,所有id地址一样,包含子对象地址。

        浅拷贝:指重新分配一块内存,创建一个新的对象,里面的元素是原对象中子对象的引用(即拷贝父对象,不会拷贝对象的内部的子对象)。

        注意,此处要对原对象中的子对象类型作情况讨论。

        没有对原对象的所有内部对象进行复制引用,仅对外层子对象复制,所以叫浅拷贝。

        新对象的id地址与原对象不同,但是其子对象地址引用有部分相同,具体视子对象的可变或不可变类型而不同——这里关联到第一步所讲的可变对象和不可变对象的概念

        若子对象为可变类型,作出赋值更改时,子对象的值会更改而不是开辟新内存地址,即不更改子对象的id地址,故新对象也会跟着同步更新;反之,子对象为不可变类型,则会开辟新的内存地址,原对象的子对象指向新的id地址,但是新对象的子对象还是指向原来的id地址,所以不会同步更新。

        

浅拷贝有三种形式: 切片操作,列表解析,工厂函数,copy模块中的copy函数。

如: a = [1,2,[3,4]]

切片操作:b = a[:]

列表解析式:b = [ i for i in a ] 

工厂函数:b = list(a)

copy函数:b = copy.copy(a)

浅拷贝中的元素,是原对象中子对象的引用,因此,如果原对象中的元素是可变的,改变其也会影响拷贝后的对象,存在一定的副作用。

        深拷贝:完全拷贝了父对象及其子对象,深拷贝出来的对象是一个全新的对象,不再与原来的对象有任何关联。

        完整地对原对象进行复制引用(包含多层嵌套的对象),新对象产生新的id地址,子对象若为可变类型则会开辟新的id地址,否则仍指向旧的id地址。同样的,结合第一步的可变对象和不可变对象的赋值概念会更容易理解。

        Python 中以copy 模块的 deepcopy 方法,来实现对象的深度拷贝,例如b = copy.copy(a)。

        深度拷贝也不是完美的,往往也会带来一系列问题。如果被拷贝对象中存在指向自身的引用,那么程序很容易陷入无限循环:

import copy
x = [1]
x.append(x)

x
[1, [...]]

y = copy.deepcopy(x)
y
[1, [...]]

      最后,附几张图方便理解:

 

个人思路,供参考,若有错误,欢迎指正。

参考:

https://zhuanlan.zhihu.com/p/54011712

https://zhuanlan.zhihu.com/p/152244101

https://www.runoob.com/w3cnote/python-understanding-dict-copy-shallow-or-deep.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值