在工作中,常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题。为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用。为了生成这个副本,就产生了拷贝。今天就说一下Python中的深浅拷贝问题。

一、深浅copy

1.  赋值运算


  1. l1 = [1, 2, 3, [22, 33]]
  2. l2 = l1
  3. l1.append(666)
  4. print(l1)  # [1, 2, 3, [22, 33], 666]
  5. print(l2)  # [1, 2, 3, [22, 33], 666]

图解:

注意:l2 = l1是一个指向,是赋值,和深浅copy无关。

2.  浅copy

其实列表是一个一个的槽位,每个槽位存储的是该对象的内存地址


  1. #例1. 给大列表添加元素
  2. l1 = [1, 2, 3, [22, 33]]
  3. l2 = l1.copy()
  4. # 或者下面这种方式,也是浅copy
  5. # import copy
  6. # l2 = copy.copy(l1)
  7. l1.append(666)
  8. print(l1)  # [1, 2, 3, [22, 33], 666]
  9. print(l2)  # [1, 2, 3, [22, 33]]
  10. #例2. 给小列表添加元素
  11. l1 = [1, 2, 3, [22, 33]]
  12. l2 = l1.copy()
  13. l1[-1].append(666)
  14. print(l1)  # [1, 2, 3, [22, 33, 666]]
  15. print(l2)  # [1, 2, 3, [22, 33, 666]]、
  16. 例3. 将l1列表中第一个元素改为6
  17. l1 = [1, 2, 3, [22, 33]]
  18. l2 = l1.copy()
  19. l1[0] = 6
  20. print(l1)  # [6, 2, 3, [22, 33]]
  21. print(l2)  # [1, 2, 3, [22, 33]]

图解:

例1

例2

例3

小结:

浅copy:会在内存中新开辟一个空间,存放这个copy的列表,但是列表里面的内容还是沿用之前对象的内存地址。

3.  深copy


  1. import copy
  2. l1 = [1, 2, 3, [22, 33]]
  3. l2 = copy.deepcopy(l1)
  4. l1.append(666)
  5. print(l1)  # [1, 2, 3, [22, 33], 666]
  6. print(l2)  # [1, 2, 3, [22, 33]]

图解:

本质如下图:

但是python对深copy做了一个优化,将可变的数据类型在内存中重新创建一份,而不可变的数据类型则沿用之前的,所以内存中是下面这样的:

小结:

深copy:会在内存中开辟新空间,将原列表以及列表里面的可变数据类型重新创建一份,不可变数据类型则沿用之前的。

为什么Python默认的拷贝方式是浅拷贝?

  • 时间角度:浅拷贝花费时间更少。
  • 空间角度:浅拷贝花费内存更少。
  • 效率角度:浅拷贝只拷贝顶层数据,一般情况下比深拷贝效率高。

总结:

  • 不可变对象在赋值时会开辟新空间。
  • 可变对象在赋值时,修改一个的值,另一个也会发生改变。
  • 深、浅拷贝对不可变对象拷贝时,不开辟新空间,相当于赋值操作。
  • 浅拷贝在拷贝时,只拷贝第一层中的引用,如果元素是可变对象,并且被修改,那么拷贝的对象也会发生变化。
  • 深拷贝在拷贝时,会逐层进行拷贝,直到所有的引用都是不可变对象为止。
  • Python 有多种方式实现浅拷贝,copy模块的copy 函数 ,对象的 copy 函数 ,工厂方法,切片等。
  • 大多数情况下,编写程序时,都是使用浅拷贝,除非有特定的需求。
  • 浅拷贝的优点:拷贝速度快,占用空间少,拷贝效率高。

想要获取更多Python学习资料可以加我QQ:2955637827

图解Python中深浅拷贝的更多相关文章

  1. python中深浅拷贝

    python的复制,深拷贝和浅拷贝的区别   在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...

  2. Python中深浅拷贝 垃圾回收与 super继承(六)

    1 python拷贝 深拷贝,浅拷贝 与引用三者的区别 import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 b = a #赋值,传对象的引用 c = copy ...

  3. Python的深浅拷贝

    Python的深浅拷贝 深浅拷贝 1. 赋值,对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量并不是复制一份内容 list1 = [']] list2 = list1 p ...

  4. Python原理 -- 深浅拷贝

    python原理 -- 深浅拷贝 从数据类型说开去 str, num : 一次性创建, 不能被修改, 修改即是再创建. list,tuple,dict,set : 链表,当前元素记录, 下一个元素的位 ...

  5. Python之深浅拷贝

    拷贝就是拷贝,何来深浅之说? Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果 其实这个是由于共享内存导致的结果 浅拷贝 l1 = [1,2,3 ...

  6. 24、简述Python的深浅拷贝以及应用场景

    深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...

  7. Python入门-深浅拷贝

    首先我们在这里先补充一下基础数据类型的一些知识: 一.循环删除 1.前面我们学了列表,字典和集合的一些操作方法:增删改查,现在我们来看一下这个问题: 有这样一个列表: lst = ['周杰伦','周润 ...

  8. day2学python 数据类型+深浅拷贝+循环

    数据类型+深浅拷贝+循环 别的语言的数组 python不用定义 直接使用 color=['红','橙','黄','绿','青','蓝','紫'] print(color[1:3]) //打印[1,3) ...

  9. 简述Python的深浅拷贝以及应用场景

    深浅拷贝的原理 深浅拷贝用法来自copy模块. 导入模块:import copy 浅拷贝:copy.copy 深拷贝:copy.deepcopy 字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝 ...

随机推荐

  1. 【Redis】【报错】redis.exceptions.ResponseError: DENIED Redis is running in protected mode

    (一)报错前提 写flask 项目的时候,因为连接了私有云中的redis地址指定了IP host,启动项目的时候报错 (二)解决方法 首先要切换到root用户 root@:/etc/redis# pw ...

  2. docker中启动容器提示端口被占用

    docker中启动容器提示端口被占用,但是 docker ps -a 查不到信息 1.查询端口被占用的id netstat -ntpl |grep 3306 2.杀掉该id kill -9 如果kil ...

  3. 为什么不用UUID做主键?

    不易于存储:UUID太长,16字节128位,通常以36长度的字符串表示,很多场景不适用. 信息不安全:基于MAC地址生成UUID的算法可能会造成MAC地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位 ...

  4. dubbo起停之服务注解

    开始之前建议先去了解spring的BeanDefinition可以参考下这里:https://www.jianshu.com/p/56e42e82e9a0 当用户使用注解@DubboComponent ...

  5. 推荐:国产etl调度工具Taskctl web应用版,0元永久授权

    写在前面 2020年疫情席卷全球,更是对整个市场经济造成了严重影响,年初疫情肆虐,西方世界单方面的科技.经济封锁,国际关系吃紧.....导致很多中小型企业业务链受阻,大型企业经费资金吃紧,轮班制导致公 ...

  6. Vue.js 桌面端自定义滚动条组件|vue美化滚动条VScroll

    基于vue.js开发的小巧PC端自定义滚动条组件VScroll. 前段时间有给大家分享一个vue桌面端弹框组件,今天再分享最近开发的一个vue pc端自定义滚动条组件. vscroll 一款基于vue ...

  7. IDEA社区版(Community)和付费版(UItimate)的区别

    比对类型 Ultimate(终极版,付费) Community(社区版,免费) 语言支持 Java Java Groovy Groovy Kotlin Kotlin Scala(通过插件) Scala ...

  8. Cys_Control(一) 项目搭建

    一.基础工程搭建 Cys_Controls Cys_Resource(注:一般类库默认不能引入资源文件,故直接创建Custom Control Library) Cys_Demo 删除默认文件夹及类, ...

  9. moviepy AudioClip的max_volume方法报错ValueError: operands could not be broadcast together with shapes(2,)

    ☞ ░ 前往老猿Python博文目录 ░ 在<moviepy音视频剪辑:AudioClip的max_volume方法报TypeError: bad operand type for abs(): ...

  10. Python中函数是否能使用全局变量?

    Python函数中的变量,既可以使用局部变量(本地名字空间的变量),也可以使用全局变量(全局名字空间的变量),函数在执行查找变量只读时,先在局部变量中查找,找不到再查到全局变量中查找.因此当局部变量和 ...