Python 关于赋值和深浅拷贝的问题

首先,这三种形式是有关联的,这三种形式应该与对象和身份判断共同理解,分析对象的id和赋值的引用是关键。

最根本的原则:深浅拷贝的区别是用在组合对象中,像是列表、字典、元祖、数字、字符的几种组合,这样深浅拷贝有区别。

赋值,拷贝对象的引用,id相同。


a=5
b=a
print(id(a),id(b))

输入结果的id 一定是相同的。

2744560517488 2744560517488

针对深浅拷贝,需要从组合类型中分析,浅拷贝是复制数据,但是不复制引用,总结来说就是只是把数据给了一个新的空间,但是与原来的数据还有着千丝万缕的关系,不是一个完整的独立个体。

ls1=[1,[2,3]] #创建列表对象并赋给变量ls1
ls2=ls1[:]  #从前到后所有进行读取  #通过ls1[:]将ls1的所有元素切片生成新对象并赋给ls2
print('ls1和ls2的值分别为:',ls1,ls2)
print('ls1和ls2的内存地址分别为:',id(ls1),id(ls2))
ls1和ls2的值分别为: [1, [2, 3]] [1, [2, 3]]
ls1和ls2的内存地址分别为: 1718324918528 1718328057920

如上的结果,值完全复制了,给了一个新的内存地址,这是浅拷贝,当然深拷贝也是一个新的内存地址,最大的区别是赋值和里面元素的id.

print('ls1[1]和ls2[1]的内存地址分别为:',id(ls1[1]),id(ls2[1]))
ls1[1][0]=5 #将ls1下标为1的列表元素(即ls[1])中下标为0的元#素值修改为5
print('ls1和ls2的值分别为:',ls1,ls2)

从这个结果就可以看出,id相同,值相同,因为 这两个数据之间的引用关系仍旧存在,所以导致这样的结果。

ls1[1]和ls2[1]的内存地址分别为: 1718324631296 1718324631296
ls1和ls2的值分别为: [1, [5, 3]] [1, [5, 3]]

对于深拷贝来说,会形成两个完全独立的个体。

import copy #导入copy模块
ls1=[1,[2,3]] #创建列表对象并赋给变量ls1
ls2=copy.deepcopy(ls1) #通过调用deepcopy函数复制ls1生成新对象并赋给ls2
print('ls1和ls2的值分别为:',ls1,ls2)
print('ls1和ls2的内存地址分别为:',id(ls1),id(ls2))
print()
print('ls1[1]和ls2[1]的内存地址分别为:',id(ls1[1]),id(ls2[1]))
ls1[1][0]=5 #将ls1下标为1的列表元素(即ls[1])中下标为0的元素值修改为5
print('ls1和ls2的值分别为:',ls1,ls2)
ls1和ls2的值分别为: [1, [2, 3]] [1, [2, 3]]
ls1和ls2的内存地址分别为: 1940159427904 1940159497728

ls1[1]和ls2[1]的内存地址分别为: 1940156221312 1940159425408
ls1和ls2的值分别为: [1, [5, 3]] [1, [2, 3]]

运行上述代码,可以看出,赋值后两个对象的id肯定是不同的,这点与浅拷贝一致,但是内部元素的索引已经被彻底破坏,因此,内部元素的id一定是不同的,具体其内存地址。

同样,对其中一个组合进行值的修改,另一个就不会任何变化。

这就是深浅拷贝的区别,最关键的是针对组合对象而言,才有这种性质。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星辰的小空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值