鱼C论坛

 找回密码
 立即注册
查看: 1224|回复: 5

[已解决]关于copy()

[复制链接]
发表于 2020-3-15 22:25:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
list1 = [1, 2]
list2 = [3, 4]

dict1 = {'1':list1, '2':list2}
dict2 = dict1.copy()

dict1['1'][0] = 5

result = dict1['1'][0] + dict2['1'][0]
print(result)

以上程序打印为10。dict1改变,dict2也随之改变了
====================================================

a = {'1':1, '2':2}
b = a.copy()

a['1'] = 5
result = a['1']+b['1']

print(result)

以上程序打印为6。字典a改变了,但b并没有随之改变
===========================================

请问,同样是copy(),为什么当字典里面的值是一个列表的时候,复制出来的另一个字典值也会发生改变呢?
最佳答案
2020-3-15 22:30:07
本帖最后由 sunrise085 于 2020-3-15 22:31 编辑

因为copy是浅拷贝,对于字典、列表等类型,浅拷贝只能复制外层,内层数据并没有完全拷贝,仍然使用的是原来的数据。
只拷贝的父对象,而不会拷贝里面的子对象,子对象仍然是原来对象的子对象,因此就出现了以上现象。
要想完全拷贝赋值,则需要使用深拷贝,即copy.deepcopy(),deepcopy()方法可以进行完全拷贝,既对父对象进行了拷贝,也对子对象进行了拷贝。是一个全新的对象了。
可以看看我之前总结的一个帖子python细节之2、变量名与标签 变量的赋值与修改
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-3-15 22:29:52 From FishC Mobile | 显示全部楼层
copy也是浅复制,只复制一层,里层还是引用相同的地址,所以要深度复制的话,就导入copy模块,使用copy.deepcopy复制
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-15 22:30:07 | 显示全部楼层    本楼为最佳答案   
本帖最后由 sunrise085 于 2020-3-15 22:31 编辑

因为copy是浅拷贝,对于字典、列表等类型,浅拷贝只能复制外层,内层数据并没有完全拷贝,仍然使用的是原来的数据。
只拷贝的父对象,而不会拷贝里面的子对象,子对象仍然是原来对象的子对象,因此就出现了以上现象。
要想完全拷贝赋值,则需要使用深拷贝,即copy.deepcopy(),deepcopy()方法可以进行完全拷贝,既对父对象进行了拷贝,也对子对象进行了拷贝。是一个全新的对象了。
可以看看我之前总结的一个帖子python细节之2、变量名与标签 变量的赋值与修改
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-15 22:36:06 | 显示全部楼层
本帖最后由 TJBEST 于 2020-3-15 22:41 编辑

copy不是深拷贝是浅拷贝


当容器的 元素是 基本类型:数字,字符串 他的copy是值 即 在内存中重新开辟一个空间
但是 如果元素是一个非基本类型 则 元素实际上在内存中存储的是一个地址 地址所在区域存储的是对象的值

比如a = [1,2,[1,2]]
在内存中是这样的
0x10(a):1 [0]| 2[1]  | 0x56[2]
0x56:1[0]|2[1]

0x表示16进制数 内存地址常用此形式
其中|用来分割对象的属性
[]用来表示 对象 的属性 或者 下标(序列) 或者 键(字典)
那么
b = a.copy()内存是这样的
0x11(b):1 [0]| 2[1]  | 0x56[2]
0x56:1[0]|2[1]
那么你修改b[2][1]=1
此时
0x56:1[0]|1[1]
a[2][1]的值就变为1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-15 22:44:01 | 显示全部楼层
sunrise085 发表于 2020-3-15 22:30
因为copy是浅拷贝,对于字典、列表等类型,浅拷贝只能复制外层,内层数据并没有完全拷贝,仍然使用的是原来 ...

明白了,看了你总结的那篇觉得非常清晰,非常感谢~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-15 22:45:31 | 显示全部楼层
hrp 发表于 2020-3-15 22:29
copy也是浅复制,只复制一层,里层还是引用相同的地址,所以要深度复制的话,就导入copy模块,使用copy.dee ...

也谢谢你~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-12 17:48

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表