对象浅复制和深复制的几个问题

一、“==”与“is”

==运算符是比较的两个对象的值,而is比较的是对象的标识。例如:

a = [1,2,3]
b = a
c=list(a) 
a == b == c ##返回True
id(a) == id(b) ##返回True
id(a) == id(c) ##返回False

这里a指向对象[1,2,3],而b是对象[1,2,3]的别名,也就是说,a和b都指向[1,2,3]这个对象,所以他们的值相同,id也相同。而c是a创建的副本,a和c的值相同,但是id标识不同。

二、浅复制问题

l1 = [3, [66, 55, 44],(7, 8, 9)]
l2 = list(l1)
l1.append(100)
l1[1].remove(55)
print("l1:", l1) ##l1: [3, [66, 44], (7, 8, 9), 100]
print("l2:", l2) ##l2: [3, [66, 44], (7, 8, 9)]

l2[1] += [33,22] ##l1: [3, [66, 44, 33, 22], (7, 8, 9), 100]
l2[2] += (10,11) ##l2: [3, [66, 44, 33, 22], (7, 8, 9, 18, 11)]

首先l1创建了一个副本l2,然后对l1追加100,又删除了l1列表元素55,从结果中看到,l1追加的元素对l2没有影响,但是l1删除的元素对l2有影响了,为什么呢,从查看他们的id标识可以看出来:

id(l1) == id(l2) ##返回False
id(l1[1]) == id(l2[1]) ##返回True

这是l1和l2绑定了同一个列表。由下面的交互动画可以看到:
这里写图片描述
这是l1列表
这里写图片描述
这是l2列表,可以看出,他们指向同一个对象。
这里写图片描述
在增加100时,只有l1增加了。
这里写图片描述
而删除55时,这是他们公共的。
这里写图片描述
当列表增加元素时,这是就地修改,即两个都改变了。
这里写图片描述
而当对l2修改元组时,它没有就地修改,而是新创建了一个对象,因为元组是不可变的。
因此,在使用可变的对象时,要改变其内容应格外注意。

再看copy模块

copy模块中有两个函数,分别是浅复制copy和深复制deepcopy。

import copy
s1 = [3,[12,23],(1,2,5)]
s2 = copy.copy(s1)
s3 = copy.deepcopy(s1)
s1[1].append(200)
s2[2] += (0,0)
print(s1)
print(s2)
print(s3)

[3, [12, 23, 200], (1, 2, 5)]
[3, [12, 23, 200], (1, 2, 5, 0, 0)]
[3, [12, 23], (1, 2, 5)]

s1, s2, s3它们的id都不相同,s1和s2如上述所讲,但s3是一个新对象,看一看以下交互图:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
虽然deepcopy复制的时候,s1,s2,s3最后一个元组的id虽然相同,但是s2改变的是元组,它若一经修改就变为另一个对象了,所以对深复制没有影响。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值