深浅copy

深浅copy对比

列表赋值

例如:列表a=[‘a’, 'b', 'c', 'd', 1, 2, 3],当执行代码b=a,可以得到b=[‘a’, 'b', 'c', 'd', 1, 2, 3],具体实现如下:

>>> a=['a', 'b', 'c', 'd', 1, 2, 3]
>>> b=a
>>> id(a),id(b)
(2805890045000, 2805890045000)

可以看出来,这里两个列表a和b的内存地址是一样的,那么当我们改变列表a中的某一个元素时,b列表会发生什么结果呢?

>>> a[0]='jersey'
>>> a
['jersey', 'b', 'c', 'd', 1, 2, 3]
>>> b
['jersey', 'b', 'c', 'd', 1, 2, 3]
>>> id(a),id(a[0]),id(b),id(b[0])
(2805890045000, 2805890018920, 2805890045000, 2805890018920)

我们可以看到id(a)和id(b)是一样的,id(a[0])和id(b[0])也是一样的。这意味着,当我们将变量b指向a列表时,b列表和a列表共享同一个内存地址,那么当列表a中的元素发生了变化,那么共享该内存地址的列表b里面的元素也是同时发生变化。

浅copy

那么有没有方式,能够像字符变量那样,当改变第一个变量的时候,第二个变量不受影响呢?如下程序所示,当将a的值赋给b后,在改变a,b的值并不会收到任何的影响:

>>> a=1
>>> b=a
>>> b
1
>>> a=2
>>> a,b
(2, 1)

这里,我们就要了解为什么会这样?其实赋值并不是说把变量改变了。我们知道:

  1. a=1,计算机实际上是开辟了一个内存地址,把1放进去,让后让变量指向该1的内存地址;
  2. b=a,实际上是将变量b同时指向1的内存地址;
  3. 当进行到第三步a=2的时候,计算机是重新开辟了一块新的内存地址,将2放入其中,让a指向这个新的内存地址。然而,b指向的内存地址仍旧为1的内存地址,所以没有发生改变。

同理可得,那我们如果实现可以改变列表中的某个元素的功能,实际上就是需要让两个列表的内存地址是不同的,那么在修改的时候,就互不干扰。这里就可以引出.copy()操作符。如下面代码所示:

>>> a=['a', 'b', 'c', 'd', 1, 2, 3]
>>> b=a.copy()
>>> b
['a', 'b', 'c', 'd', 1, 2, 3]
>>> a[0]='A'
>>> a
['A', 'b', 'c', 'd', 1, 2, 3]
>>> b
['a', 'b', 'c', 'd', 1, 2, 3]

不难发现,当改变a列表中第一个元素的值的时候,b列表没有发生任何改变,这就是因为通过.copy()这个操作符,其实是计算机开辟了一个新的id,将a列表赋值到这个新的id上,让变量b指向这个id,那么当改变a中的元素也就和b列表没有什么关系了~

深copy

那么,当我们在一个列表里面,嵌套一个新的列表会发生什么情况呢?让我们先看看代码实现吧~

>>> a = ['alex', 'shanshan', 24, ['longting', 22]]
>>> b=a.copy()
>>> b
['alex', 'shanshan', 24, ['longting', 22]]
>>> a[3][0]='jersey'
>>> a
['alex', 'shanshan', 24, ['jersey', 22]]
>>> b
['alex', 'shanshan', 24, ['jersey', 22]]

我们看的出来,当嵌套的新列表里面的元素发生了改变之后,按理来说不应该发生变化的b列表,却同使发生了变化~这是为什么呢?
通过我们上面浅copy中的分析,如果两个列表是指向同一个内存地址,那么当一个列表发生变化的时候,那么另外一个就会发生变化,那么现在就让我们来验证一下这两个嵌套的新列表的id吧~

>>> id(a[3]),id(b[3])
(2805890044744, 2805890044744)

我们发现,正如我们所料,它们两个嵌套的新列表指向的是同一个内存地址。这表明,当最外层的列表(本示例中为a)进行copy的时候,只是开辟了一个新的内存地址,并将当前列表复制进去,让新的变量(本示例中为b)指向这个内存地址。然而,却没有给嵌套的列表开辟新的内存地址,因此,这两个列表中的嵌套列表仍为共享同一个地址,所以某一个列表中元素发生变化的时候,另外一个同时发生变化。

这个时候就需要引出深度复制的概念:也就是当复制的时候,连同里面的嵌套,也一同开辟新的内存地址进行复制,两个列表完全独立,互不干扰,一个发生变化的时候,第二个不发生任何变化。但是不建议这么操作,因为极其占用内存!!~~操作码为:copy.deepcopy(列表名)

转载于:https://www.cnblogs.com/GGGGGGZX/p/8911611.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql5 varchar_MYSQL 5.7 VARCHAR 类型实验

MYSQL 的VARCHAR 类型字段的最多能存储多少字符?模糊记得 VARCHAR 最多能存65535个字符,真的吗?理论上,一个字符类型能存的字符数量跟选取的编码字符集和存储长度限制肯定是有关系的,字符编码长度越小,长度…

《React源码解析》系列完结!

前言 距离第一篇《React源码解析(一)》已经过去将近4个月的时间,由于是我第一次进行源码解析相关的写作,思路和文笔还不够成熟。一百多天以来,我基于读者反馈反思这几篇文章中的不足,同时也在不断学习借鉴其他优秀作者的写作方法…

优化Java序列化– Java,XML,JSON,Kryo,POF

也许我很天真,但是我一直认为Java序列化肯定是将Java对象序列化为二进制形式的最快,最有效的方法。 毕竟Java是第7个主要发行版,所以这不是新技术,并且由于每个JDK似乎都比上一个快,因此我错误地认为序列化现在必须非常…

html5 css 字体加粗,HTML和CSS实现字体加粗的三种方法

大家在浏览网站时有没有注意到,页面中有些文字或字体加粗了,正在学习HTML和CSS的小伙伴,你知道HTML如何给文字加粗吗?CSS怎么设置字体加粗呢?这篇文章给大家总结了给字体和文字加粗的三种方法,包括HTML中的…

浅谈模拟退火

核心思想 模拟退火十分好写,它的核心思想就是: 每一次降温都可以从当前状态转移到另一种相近状态(没有严格定义,可以自己想产生相近解的方法) 如果那个相近状态的答案更优,当然转移到那种状态! …

如何应用前端技术唤起app及判断用户来源及与原生交互的原理

做唤起时需要native端进行配合, h5唤起app这种需求是常见的。在移动为王的时代,h5在app导流上发挥着重要的作用。 目前我们采用的唤起方式是url scheme(iOS,Android平台都支持),只需原生APP开发时注册scheme, 那么用户…

mysql 设置client char_mysql编码问题:show variables like “%char%”

mysql编码设置mysql> SHOW VARIABLES LIKE character_set_%;------------------------------------------------------| Variable_name | Value |------------------------------------------------------| character_set_client | latin1 || character_set_connection | la…

虾扯蛋之函数防抖和节流

背景 今天在coding的时候,做了一个搜索框,也正是这个搜索框,让我和后台小伙伴直接由铁磁变为塑料兄弟。那到底发生啥了呢?其实很简单,其实很无奈,就是我用王者的手速把他的接口访问崩了! 我们在…

四川省内二本计算机公立好的大学排名,四川有哪些二本院校是公立的?附四川省公立二本大学排名及分数线...

选择科目测一测我能上哪些大学选择科目领取你的专属报告>选择省份关闭请选择科目确定v>四川省内的公办大学一直以来都是历年高考生及家长关注的重点,本篇文章我将针对“四川省有多少所二本公立大学?有哪四川省内的公办大学一直以来都是历年高考生及…

NetBeans 7.4 Beta提示警告无效的异常处理

有许多例子说明Java异常处理可能比首次出现时要困难得多,Josh Bloch专门将一整章的《 Effective Java》 (两个版本)专门用于异常处理。 Java中的检查异常模型 仍然 “ 有争议” 。 我很高兴看到我最近下载的NetBeans 7.4 beta有一些提示&…

平心静气

昨天做一个功能的时候需要修改ofbiz代码,增加关联的表和查询字段,本以为很简单,照着写一下就好了,但是一直报错.临近下班,苦思冥想没有找到原因,八点左右不得已回家了. 第二天早上半个小时搞定.关键还是要平心静气,其实只是一个大小写的问题,由于大小写不匹配,没有匹配到对应的…

mysql5.7.17解压版安装_Windows中 MySQL5.7.17解压版安装步骤

1、先去MySQL官网下载。当前最新版是5.7.19,可能安装方法不同了,本人测试没有安装成功,若有安装成功的朋友,希望分享一下安装步骤。2、将下载的压缩包解压出来,然后在“MySQL解压目录”中新建“data”文件夹。如下图&a…

大学计算机结课论文怎么写,大学本科计算机论文格式_大学本科计算机毕业论文范文...

导读:如何撰写出满意的大学本科计算机论文是现在很多人都为之苦恼的问题之一,而论文的撰写也并非易事,必定是需要花费很多心思和汗水的,本论文分类为大学计算机论文,下面是小编为大家整理的几篇大学本科计算机论文范文…

关于Java和Scala同步的五件事你不知道

实际上,所有服务器应用程序都需要在多个线程之间进行某种同步。 大多数同步工作是在框架级别为我们完成的,例如通过我们的Web服务器,数据库客户端或消息传递框架。 Java和Scala提供了许多组件来编写可靠的多线程应用程序。 这些包括对象池&am…

Keepalived详解之 - LVS(IPVS)管理工具ipvsadm使用指南

ipvsadm是什么? ipvsadm是用来配置、维护或者查看Linux内核当中virtual server table的一个工具, LVS(Linux virtual server)能基于一个集群当中的两个或者多个节点来创建弹性网络服务, 集群中的处于激活状态的节点能将服务请求重定向到一组实际提供服务的主机当中, 提供包括T…

精读《你不知道的javascript》中卷

前言 《你不知道的 javascript》是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途。本书《你不知道的javascript》中卷介绍了该系列的两个主题:“类型和语法”以…

mysql触发器区分新增 修改_MySQL触发器 , 判断更新操作前后数据是否改变

改动表为user , 改动后将部分信息写入cfq_tab表1. 新增触发器create TRIGGER cfq_on_user_addafter insert on userfor each ROWBEGINinsert into cfq_tab(id,type_id,type,status) values (null,new.UID,1,0);end;2. 修改触发器 , 判断修改前后数据是否变动//DROP TRIGGER IF…

三年级计算机课画曲线,三年级上册信息技术曲线工具教案

教材分析《嬉戏山水间—曲线工具》本课教学时间一课时,主要内容是学习在Windows下学会画图软件中“曲线”工具的使用方法。根据教材的编排,本课之前,学生已学会了画图软件中椭圆和直线工具、多边形工具的使用,已经具备了画图软件的…

如何使用不同的记录器实现配置SLF4J

将slf4j库用作Java应用程序日志记录API层有很多好处。 在这里,我将展示一些示例,说明如何与不同的记录器一起使用和配置它。 您可以将slf4j视为Java接口,然后在运行时需要一个实现(仅一个)来提供实际的日志记录详细信…

Presto 学习

Presto 基础知识与概念学习可以参考这些博客: presto 0.166概述 https://www.cnblogs.com/sorco/p/7060166.html Presto学习-presto介绍 https://blog.csdn.net/paicMis/article/details/78516475 Presto必知必会 https://blog.csdn.net/jiangshouzhuang/article/de…