1:Why copy?

笔者最近在一次比赛中发现了一个奇怪的东西

Class troop:def __init__(sefl,x,x,x,x):xxxdef A():self.tmp = []self.res = []def DFS(self):if xxxx:self.res.append(self.tmp)

在上面这份代码中,最后发现res中的文件全部都是空列表。仔细查了一下才发现这是有Python的内存机制引起的。
下面举一个简单的例子:

a = [1]
b = []
b.append(a)
print(b)
a.pop()
print(b)

其结果显示如下:

很奇怪,为什么我修改a中的值会造成b的改变?

上面这个情况造成的原因是因为b中的值直接对a进行了引用,即内存地址是一样的。看不懂不要紧,请牢牢记住这句话,先在心里默念三遍,然后看下面的例子。

will = ["乐乐熊", 24, ["数学", "语文", "英语"]]
wilber = will
print (id(will))
print (will)
print (id(ele) for ele in will)
print (id(wilber))
print (wilber)
print ([id(ele) for ele in wilber])will[0] = "闭闭熊"
will[2].append("物理")
print (id(will))
print (will)
print (id(ele) for ele in will)
print (id(wilber))
print (wilber)
print ([id(ele) for ele in wilber])

其运行结果如下:

学术解释1:

首先,我们创建了一个名叫will的变量,这个变量指向一个列表,且列表里面有三个元素,通过打印我们能够看到3个元素的内存位置。
然后,通过will变量对wilber变量进行赋值,那么wilber变量将指向will变量对应的对象(内存地址),也就是说"wilber is will",“wilber[i] is will[i]”(即在Py中,对象的赋值都是进行对象引用(内存地址)传递)
最后,由于wiilber和will指向同一个列表,所以针对will的操作都会反馈到wilber上(PS,这里我专门用了一个不可变类型str用来说明当修改不可变类型的时候会替换旧的对象,产生一个新的地址)

画图解释1

2:浅拷贝

让我们来看看浅拷贝的效果

import copy
will = ["乐乐熊", 24, ["数学", "语文", "英语"]]
wilber = copy.copy(will)
print (id(will))
print (will)
print ([id(ele) for ele in will])
print (id(wilber))
print (wilber)
print ([id(ele) for ele in wilber])print('=====================')
will[0] = "闭闭熊"
will[2].append("物理")
print (id(will))
print (will)
print ([id(ele) for ele in will])
print (id(wilber))
print (wilber)
print ([id(ele) for ele in wilber])

其结果为

学术解释2

首先,我们创建了一个名叫will的变量,这个变量指向一个列表,且列表里面有三个元素,通过打印我们能够看到3个元素的内存位置。
然后,通过copy模块里面的浅拷贝函数copy(),对will指向的对象进行浅拷贝,然后浅拷贝生成的新对象赋值给wilber变量。

  1. 浅拷贝会创建一个新的对象,这个例子中"wilber is not will"
  2. 但是,对于对象中的元素,浅拷贝就只会使用原始元素的引用(内存地址),也就是说"wilber[i] is will[i]"

当对will进行修改的时候
3. 由于list的第一个元素是不可变类型,所以will对应的list的第一个元素会使用一个新的对象1466513880528
4. 但是list的第三个元素是一个可变类型,修改操作不会产生新的对象,所以will的修改结果会相应的反应到wilber上

图像解释


在执行操作后

这就是浅拷贝的原理。当我们使用切片list[:]或者函数copy.copy的时候就会产生浅拷贝的效果。

3:深拷贝

我们在上面的浅拷贝中又发现了问题,因为内存地址一样,那么我对will里面的可变类型进行操作的话,那岂不是我的wilber数据也会发生变化?解决可变类型数据这个问题就需要用到深拷贝
完成深拷贝只需要将上述代码中wilber = copy.copy(will) 替换为 *wilber = copy.deepcopy(will)*即可。
执行结果如下:

画图解释


注意这里深拷贝可变对象地址已经不一样了!在执行操作之后

灵魂画手教你浅拷贝与深拷贝相关推荐

  1. C# 浅拷贝与深拷贝区别 解惑篇

    问题起源: 昨天被同事问到一个浅拷贝与深拷贝区别的问题,说实在的,记得在学校时在书在看过相关概念区别. 只是,那时的在校生,又有几个能对书本上那写的尽量让鬼都看不懂知识能清晰的理解呢. 工作后虽然也有 ...

  2. 【Python成长之路】快速理解复制、浅拷贝、深拷贝

    哈喽大家好,我是鹏哥. 今天想聊聊的主题是 -- 浅拷贝/深拷贝. ~~~上课铃~~~ 赤伶HITA - 赤伶 1 写在前面 浅拷贝.深拷贝的知识点,在python笔试和面试的过程中,经常被作为考题来 ...

  3. 【彻底讲明白浅拷贝与深拷贝】

    一.数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型. 1.基本数据类型的特点:直接存储在栈(stack) ...

  4. Java中的浅拷贝与深拷贝

    一.引用拷贝与对象拷贝 class Person implements Cloneable{private String name;private int age;...省略get和set方法 pro ...

  5. js之浅拷贝和深拷贝

    js数据类型主要分基本数据类型和引用数据类型.前者包括Number,String等,后者主要是Object,因此以下会针对不同的数据类型来分析,需要的朋友可以参考一下 1.js内存 js内存,或者说大 ...

  6. 43 JavaScript中的浅拷贝与深拷贝

    技术交流QQ群:1027579432,欢迎你的加入! 欢迎关注我的微信公众号:CurryCoder的程序人生 1.浅拷贝与深拷贝 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用. 深拷贝拷贝多层,每 ...

  7. 【进阶4-1期】详细解析赋值、浅拷贝和深拷贝的区别

    一.赋值(Copy) 赋值是将某一数值或对象赋给某个变量的过程,分为下面 2 部分 基本数据类型:赋值,赋值之后两个变量互不影响 引用数据类型:赋址,两个变量具有相同的引用,指向同一个对象,相互之间有 ...

  8. C# 之String以及浅拷贝与深拷贝

    C# 之String以及浅拷贝与深拷贝  一.String到底是值类型还是引用类型 MSDN 中明确指出 String 是引用类型而不是值类型,但 String 表面上用起来却像是值类型,这又是什么原 ...

  9. clone是深拷贝还是浅拷贝_Cloneable接口的作用与探索理解浅拷贝与深拷贝

    导读:本文将主要讨论设计模式--原型模式中,关于cloneable接口及浅拷贝与深拷贝的概念. 原型模式的理解 关于原型模式的理解,我在网上发现一个有趣且助于理解原型模式的例子在这里分享一下:火影忍者 ...

最新文章

  1. 学生成绩管理系统python课程设计,简易学生成绩管理系统Python
  2. 拆分工作簿为多个文件_掌握这几行代码,快速拆分Excel工作簿(内含源码)
  3. ML之DR之SVD:SVD算法相关论文、算法过程、代码实现、案例应用之详细攻略
  4. 视觉SLAM回环检测、词袋模型和视觉位置识别--论文记录和实验简析
  5. java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized
  6. 数据库51年来十八件大事年表
  7. http://kylin.apache.org/development/new_metadata.html
  8. 百度手机输入法 android ctrl,百度手机输入法旧版本
  9. python-docx处理word文件指定页面批量打印
  10. ***测试执行标准(Penetration Testing Execution Standard:PTES)
  11. 轻松搞定——JAVA实现DOC转PDF功能
  12. 【原创】关于改变电脑默认安装地址后桌面快捷键显示“指定路径不存在”错误的解决方法之一
  13. 线性代数术语中英文对照
  14. 3W字,Docker 从入门到精通
  15. python字符串相减
  16. 华为mate30和mate30pro的区别
  17. 数据库设计的重要性和设计原则
  18. Excel中如何进行快速单位换算
  19. Jmeter定时器之吞吐量整形定时器jp@gc Throughput Shaping Timer
  20. 对于程序员:如何处理干扰和打扰

热门文章

  1. js 伪数组(类数组)与数组的区别
  2. LeetCode 热题 HOT 100 -------160. 相交链表(链表)206. 反转链表(递归、回溯)
  3. linux find工作原理,Linux基础教程:find 与 xargs
  4. java实现qq邮箱发送附件和图片
  5. Pytorch房价预测
  6. 阿里云服务器密码忘了怎么修改
  7. 深度揭密SSD中的原片-白片-黑片:莫贪小便宜
  8. streamx平台部署
  9. PDF文件怎么修改,如何删除其中一页
  10. 台式计算机怎么加一个硬盘,台式电脑硬盘怎么多安装一个?电脑安装多加一块硬盘的方法...