python:一个Demo直接剖析深浅拷贝核心区别

Demo 

import copy

a = [1, 2, 3]
b = [1, 2, 3]
c = a.copy()
a.append(4)
print(id(a), a)
print(id(b), b)
print(id(c), c)

d = [1, 2, 3, {"测试":"123"}]
e = d.copy()
f = copy.deepcopy(d)
e[3]["测试"] = "demo"
print(id(d), d)
print(id(e), e)
print(id(f), f)

2980371881920 [1, 2, 3, 4]
2980371734784 [1, 2, 3]
2980371881088 [1, 2, 3]
2980371880832 [1, 2, 3, {'测试': 'demo'}]
2980371881728 [1, 2, 3, {'测试': 'demo'}]
2980371881664 [1, 2, 3, {'测试': '123'}]

浅拷贝

首先,浅拷贝,将列表中所有内容复制一遍,赋值给新的列表对象,这时候生成的新的列表对象,所以id()看到的内存地址是不同的。新列表中所有元素存放的地址,和原列表所有元素存放地址,是相同的,因为两个列表中的内容也是相同的。

问1:为什么a列表新增元素,c列表不会改变?

答1:因为a c列表是不同的对象,两个没有关系。

问2:为什么a列表更新表格中的已有内容,c列表页不会改变?

答2:因为a c列表存放的,都是字符串或者数字,每次修改其实是返回一个新的内容,也可以说是直接把元素指向新的地址。a修改只会影响a的列表。c列表的元素地址还是指向原来的地址。

问3:为什么d列表修改以后,浅拷贝的e列表会跟着修改,而深拷贝的f列表不会跟着修改?

答3:同答2中所说,浅拷贝copy只把列表中的元素或者说元素保存的内存地址复制。但是这里d列表中修改的是字典对象,字典对象不像字符串或者数字修改后返回一个新的对象,字典对象修改后只修改内容,对象还是原来那个对象,地址还是那个地址,因为浅拷贝的e列表根据拷贝的地址还是找到了修改后的字典对象。

深拷贝

那么为什么深拷贝不同呢?因为深拷贝是直接深层遍历了d列表中所有元素,是直接把字典里所有的内容也复制走了,这里新列表存放的字典也是一个新的对象。因此修改d列表的字典对象,不会影响e列表。

需要注意的是,这种情况不止字典对象会出现,只要是多层存储的都会出现。比如list中的list,dict,包含多个元素的class对象等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值