鱼C论坛

 找回密码
 立即注册
查看: 1063|回复: 4

[已解决]深拷贝浅拷贝之难题

[复制链接]
发表于 2023-8-4 11:43:47 | 显示全部楼层 |阅读模式

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

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

x

请问这个为什么e会随之d的改变而改变呀,浅拷贝不是指向同一个对象了吗
最佳答案
2023-8-4 11:52:42
浅拷贝是创建一个值相同的对象,用等号直接赋值才是同一个对象。

等号赋值:
  1. >>> a = [1, 2, 3]
  2. >>> b = a
  3. >>> b
  4. [1, 2, 3]
  5. >>> a[0] = 4
  6. >>> b
  7. [4, 2, 3]
  8. >>> a
  9. [4, 2, 3]
  10. >>>
复制代码


浅拷贝:
  1. >>> import copy
  2. >>> a = [1, 2, 3]
  3. >>> b = copy.copy(a)
  4. >>> # 浅拷贝
  5. >>> a[0] = 4
  6. >>> a
  7. [4, 2, 3]
  8. >>> b
  9. [1, 2, 3]
  10. >>>
复制代码

值得注意的是,如果改变列表对象中一个可变对象(比如列表)的值时,其浅拷贝也会发生变化。
  1. >>> import copy
  2. >>> a = [1, 2, 3, [1, 2, 3]]
  3. >>> b = copy.copy(a)
  4. >>> a[3].append(4)
  5. >>> a
  6. [1, 2, 3, [1, 2, 3, 4]]
  7. >>> b
  8. [1, 2, 3, [1, 2, 3, 4]]
  9. >>>
复制代码
但是使用深拷贝就不会有这个问题。
  1. >>> import copy
  2. >>> a = [1, 2, 3, [1, 2, 3]]
  3. >>> b = copy.deepcopy(a)
  4. >>> a[3].append(4)
  5. >>> a
  6. [1, 2, 3, [1, 2, 3, 4]]
  7. >>> b
  8. [1, 2, 3, [1, 2, 3]]
  9. >>>
复制代码
fa3bc7343e2def13b5430c36f57d34d.png

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-4 11:44:04 | 显示全部楼层
浅拷贝是指创建一个新的对象,但是新对象中的引用类型属性仍然指向原对象中的相应属性。当原对象中的引用类型属性发生改变时,浅拷贝的新对象中的相应属性也会随之改变。

在你提供的情况中,如果对象d进行了浅拷贝赋值给了对象e,那么e和d会指向同一个引用类型属性。因此,当你修改d中的引用类型属性时,e中的相应属性也会发生改变。

如果你希望e不随着d的改变而改变,你可以使用深拷贝。深拷贝会创建一个全新的对象,并且新对象中的引用类型属性也会被复制一份,而不是指向原对象中的相应属性。这样,当你修改原对象中的引用类型属性时,深拷贝的新对象不会受到影响。

以下是一个使用深拷贝的示例代码,你可以使用 copy.deepcopy() 函数来进行深拷贝:

  1. import copy

  2. d = {'key': [1, 2, 3]}
  3. e = copy.deepcopy(d)

  4. d['key'].append(4)

  5. print(d)  # 输出: {'key': [1, 2, 3, 4]}
  6. print(e)  # 输出: {'key': [1, 2, 3]}
复制代码


在这个示例中,通过使用 copy.deepcopy() 函数,我们创建了一个新的对象e,并且e中的引用类型属性被复制了一份。因此,当我们修改d中的引用类型属性时,e不会受到影响。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-4 11:51:04 | 显示全部楼层
浅拷贝:仅仅复制这个元素
  1. a = [1,2,[3,4]]
  2. # 浅拷贝
  3. b = a[:]
  4. print(b is a) # False
  5. print(a[-1] is b) # True,因为最后那个列表还是一样的
复制代码

深拷贝需要用 deepcopy()
  1. import copy
  2. a = [1,2,[3,4]]
  3. b = copy.deepcopy(a)
复制代码


现在回到你的问题:d变了,e没变
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-8-4 11:52:42 | 显示全部楼层    本楼为最佳答案   
浅拷贝是创建一个值相同的对象,用等号直接赋值才是同一个对象。

等号赋值:
  1. >>> a = [1, 2, 3]
  2. >>> b = a
  3. >>> b
  4. [1, 2, 3]
  5. >>> a[0] = 4
  6. >>> b
  7. [4, 2, 3]
  8. >>> a
  9. [4, 2, 3]
  10. >>>
复制代码


浅拷贝:
  1. >>> import copy
  2. >>> a = [1, 2, 3]
  3. >>> b = copy.copy(a)
  4. >>> # 浅拷贝
  5. >>> a[0] = 4
  6. >>> a
  7. [4, 2, 3]
  8. >>> b
  9. [1, 2, 3]
  10. >>>
复制代码

值得注意的是,如果改变列表对象中一个可变对象(比如列表)的值时,其浅拷贝也会发生变化。
  1. >>> import copy
  2. >>> a = [1, 2, 3, [1, 2, 3]]
  3. >>> b = copy.copy(a)
  4. >>> a[3].append(4)
  5. >>> a
  6. [1, 2, 3, [1, 2, 3, 4]]
  7. >>> b
  8. [1, 2, 3, [1, 2, 3, 4]]
  9. >>>
复制代码
但是使用深拷贝就不会有这个问题。
  1. >>> import copy
  2. >>> a = [1, 2, 3, [1, 2, 3]]
  3. >>> b = copy.deepcopy(a)
  4. >>> a[3].append(4)
  5. >>> a
  6. [1, 2, 3, [1, 2, 3, 4]]
  7. >>> b
  8. [1, 2, 3, [1, 2, 3]]
  9. >>>
复制代码

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
歌者文明清理员 + 5 + 3 无条件支持楼主!

查看全部评分

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

使用道具 举报

发表于 2023-8-4 11:55:07 | 显示全部楼层
tommyyu 发表于 2023-8-4 11:52
浅拷贝是创建一个值相同的对象,用等号直接赋值才是同一个对象。

等号赋值:

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-17 08:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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