python默认深拷贝_Python 深拷贝与浅拷贝

首先分享Python里面的数据类型

1、不可变类型:Number(数字)、String(字符串)、Tuple(元组)。

不可变数据类型在第一次声明赋值的时候, 会在内存中开辟一块空间, 用来存放这个变量被赋的值,  而这个变量实际上存储的, 并不是被赋予的这个值, 而是存放这个值所在空间的内存地址, 通过这个地址, 变量就可以在内存中取出数据了. 所谓不可变就是说, 我们不能改变这个数据在内存中的值, 所以当我们改变这个变量的赋值时, 只是在内存中重新开辟了一块空间, 将这一条新的数据存放在这一个新的内存地址里, 而原来的那个变量就不在引用原数据的内存地址而转为引用新数据的内存地址了.

如图:

In [11]: a = 1 #int为不可变类型,赋值

In [12]: id(a) #查看a地址

Out[12]: 4541615920In [13]: id(1) #查看数字1的地址

Out[13]: 4541615920​

In [14]: a = 2 #为a重新赋值

In [15]: id(a) #查看a地址,指向新的内存地址

Out[15]: 4541615952​

In [16]: id(2)

Out[16]: 4541615952​

In [17]: id(1)

Out[17]: 4541615920

In [28]: a = "hello" #为a赋值 hello

In [29]: b = a #将a赋值给a

In [30]: id(a)

Out[30]: 4572905712​

In [31]: id(b) #通过查看a和b的地址,说明a和b指向同一个地址

Out[31]: 4572905712​

In [32]: b = "hi" #为b赋值 hi

In [33]: a #查看a未被修改

Out[33]: 'hello'​

In [34]: id(a) #查看a地址未发生修改

Out[34]: 4572905712​

In [35]: id(b) #查看b指向新的地址,说明b=a时,是将a的引用指向b

Out[35]: 4544178736

b=a直接赋值时,默认是浅拷贝传递对象的引用而已,原始数据若为不可变类型时,被赋值的b改变时,相当于在内存中重新开辟了一块空间, 将这一条新的数据存放在这一个新的内存地址里, 而原来的那个变量就不在引用原数据的内存地址而转为引用新数据的内存地址了.

2、可变类型:Set(集合)、List(列表)、Dictionary(字典)。

当数据类型对应的变量的值发生改变时,它对应的内存地址也会发生改变,即当 e = [1,2] 时,是e指向列表[1,2]对象,而不是将e指向列表[1,2]的地址

如图:

In [10]: e = [1,2]

In [11]: id(e)

Out[11]: 4408548080​

In [12]: id([1,2]) #e指向[1,2]对象,而不是[1,2]的地址

Out[12]: 4408714656

In [10]: e = [1,2] #给变量e赋值可变类型列表[1,2]

In [11]: id(e) #查看e地址

Out[11]: 4408548080​

In [12]: id([1,2]) #查看列表[1,2]地址

Out[12]: 4408714656​

In [13]: f = e #将e赋值给f,两者共享同一个列表[1,2]对象

In [14]: id(f) #查看f地址,其实是将c指向于e的引用地址,而非列表[1,2]的实际地址

Out[14]: 4408548080​

In [15]: e[0] = 11 #通过e修改列表内元素

In [16]: e

Out[16]: [11, 2]

In [17]: f #查看f中对应元素同样被修改,验证e和f指向一个引用对象,说明f=e时,是将e的对象的地址指向f

Out[17]: [11, 2]

f = e直接赋值时,默认是浅拷贝传递对象的引用而已,原始数据e若为可变类型发生变化,被赋值的f也会做相同的改变。

3. 浅拷贝

浅拷贝是对于一个对象的顶层拷贝

通俗的理解是:拷贝了引用,并没有拷贝内容

In [36]: a = [1,2]

In [37]: b =a

In [38]: id(a)

Out[38]: 4573291056​

In [39]: id(b) #浅拷贝,a和b地址相同,说明b=a是对a引用的拷贝

Out[39]: 4573291056

通过上面的结果,说明当给一个变量赋值时。其实就是讲数据的引用复制了一份给另外一个变量 ,就是属于简单的浅拷贝

In [36]: a = [1,2]

In [37]: b =a

In [38]: id(a)

Out[38]: 4573291056​

In [39]: id(b)

Out[39]: 4573291056​

In [40]: a[0] = 11​

In [41]: a #a中元素被修改

Out[41]: [11, 2]

In [42]: b #b中元素被修改

Out[42]: [11, 2]

通过上面的结果,说明通过任何一个引用修改可变变量之后,另外一个变量的值也发生了变化。

In [24]: g = [2,3]

In [25]: h = copy.copy(g) #浅拷贝

In [26]: id(g)

Out[26]: 4409269536​

In [27]: id(h)

Out[27]: 4408716176​

In [28]: id([2,3])

Out[28]: 4408685824​

In [30]: id(2) #获取2的地址

Out[30]: 4378861392​

In [31]: id(g[0]) #获取g[0]位置的地址

Out[31]: 4378861392​

In [32]: id(h[0]) #获取h[0]位置的地址

Out[32]: 4378861392

通过上面的结果,说明浅拷贝只是对外层引用的拷贝,内层地址一样。

In [33]: a = [11,22]

In [34]: b = [33,44]

In [35]: c =[a,b]

In [36]: id(a)

Out[36]: 4408713536​

In [37]: id(b)

Out[37]: 4408547680​

In [38]: id(c)

Out[38]: 4408615712​

In [39]: d = copy.copy(c) #对c进行浅拷贝,得到d

In [40]: id(d) #查看d地址

Out[40]: 4409421248​

In [41]: id(d[0]) #查看d[0]位置元素地址,与a地址相同,说明只进行外层拷贝

Out[41]: 4408713536​

In [42]: id(d[1]) #查看d[1]位置元素地址,与b地址相同,说明只进行外层拷贝

Out[42]: 4408547680​

In [43]: a.append(55) #给a列表添加元素

In [44]: c #查看c中元素也发生变化

Out[44]: [[11, 22, 55], [33, 44]]

In [45]: d #查看d中元素也发生变化,说明是对外层的拷贝

Out[45]: [[11, 22, 55], [33, 44]]

In [46]: d.append(66) #给d中添加元素

In [47]: d #查看d中元素发生变化

Out[47]: [[11, 22, 55], [33, 44], 66]

In [48]: c #查看c中元素未发生变化,说明d未外层拷贝

Out[48]: [[11, 22, 55], [33, 44]]

通过上面的结果,说明浅拷贝只是对外层引用的拷贝,内层地址一样,修改外层,拷贝的新对象不会发生变化,修改内层元素,拷贝的新对象会发生变化。

4. 深拷贝

深拷贝是对于一个对象所有层次的拷贝(递归), 所以原始对象的改变不会造成深拷贝里任何子元素的改变

In [61]: a = [11,22]

In [62]: b = [33,44]

In [63]: c =[a,b]

In [64]: c

Out[64]: [[11, 22], [33, 44]]

In [65]: d = copy.deepcopy(c) #深拷贝得到d

In [66]: d

Out[66]: [[11, 22], [33, 44]]

In [67]: f = copy.copy(c) #浅拷贝得到f

In [68]: f

Out[68]: [[11, 22], [33, 44]]

In [69]: a.append(55) #a中添加元素55

In [70]: d #深拷贝的d中没有修改,说明是对内层也进行copy

Out[70]: [[11, 22], [33, 44]]

In [71]: f #浅拷贝的f中发生变化,说明是只对外层进行了copy

Out[71]: [[11, 22, 55], [33, 44]]

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

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

相关文章

上传 mp4 格式判断_视频如何转换成通用的MP4格式?按下这个键,10秒就能搞定...

我们在网上下载视频的时候,有很多的视频都是无法播放的,或者是需要特定的播放器才可以播放。其实,只要把这些视频的格式转换成通用的MP4格式即可。如果你还不知道怎么转换视频格式,下面就教大家两个小方法,百试百灵。一…

android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...

只要参与过安卓项目开发一两年的朋友们应该清楚,为了避免UI渲染出现异常安卓框架限制UI操作只能在主线程中进行,如果贸然在子线程做了UI操作结果会怎样?我们随便写下了如下测试代码。不出意外的话,代码执行报错抛出了名为CalledFr…

c++注释快捷键_Jupyter Notebook amp; Lab快捷键大全

Jupyter有两种模式,命令模式和编辑模式,分别有不同的快捷键。编辑模式(按键 Enter 切换):可以往单元中键入代码或文本,此时单元格被蓝色的框线包围,且命令模式下的快捷键不生效; 命令模式 (按键 Esc 开启)&…

多核cpu应用场景_CPU占用100%!PC卡顿原来可以这么解决:多场景多任务也流畅

现代生活里,不论是工作还是生活,多开软件和处理事务可以说都是家常便饭的事情。一边玩着醉心已久的游戏,一边解压着新的电影和游戏;为了查询资料,一不小心打开了数十个网页;复杂繁重的工作铸就了动辄上百兆…

swot分析法案例_项目型销售案例剖析的五大步骤

我们的案例分析方式是根据哈佛大学与中欧国际工商学院的案例分析方法来总结出我们的模式的。这种分析方法包括两种互相关联和依赖的方面。第一方面,就是要对所指定的将供集体讨论的案例,做出深刻而有意义的分析,包括找出案例所描述的情景中存…

autojs 云控_autojs websocket 核心示例代码,云控技术

//初始化方法function recordInit(scriptName){//let ipInfoJson getIP()// let ip ipInfoJson.cip// let location ipInfoJson.cnamelet deviceIMEI ,deviceBrand,deviceModel,AndroidVer,deviceWH,deviceBoard,deviceMac,AndroidIdtry {deviceBrand device.brand;//制造…

定时器和promise_从Promise链理解EventLoop

面试题new Promise(resolve > { setTimeout(()>{ console.log(666); new Promise(resolve > { resolve(); }) .then(() > {console.log(777);}) }) resolve(); }) .then(() > { new Promise(resolve > { resolve(); …

ugui源码_UGUI整体解决方案基础篇(Unity 2019)

课程介绍:本课程是UGUI系列课程的第一篇:基础篇主要是讲解UGUI的基础组件及接口的使用方法,目前UGUI是unity最常用的UI系统,这部分基础只是是每个同学都应该掌握的,这里我就是简单的讲解了用法,大家对UGUI熟…

android 实例源码解释,Android Handler 原理分析及实例代码

Android Handler 原理分析Handler一个让无数android开发者头疼的东西,希望我今天这边文章能为您彻底根治这个问题今天就为大家详细剖析下Handler的原理Handler使用的原因1.多线程更新Ui会导致UI界面错乱2.如果加锁会导致性能下降3.只在主线程去更新UI,轮询处理Handl…

amd cpu排行_最新intel和amd处理器性能排行cpu天梯图2019

现在市面上cpu厂家有很多,比如常见的intel系列的、amd系列CPU,cpu对电脑起着至关重要的作用,所以我们需要知道cpu性能的好坏,为此小编这就给大家带来最新intel和amd处理器性能排行对比天梯图,大家可以了解一下吧。inte…

python中的对象列表_Python内建的对象列表

Python内建的对象列表刚写Python肯定会遇到这样的情况,想写些什么,但又不知从何写起...在我看来问题在于我们不知道有什么东东可以拿来玩,这里列出Python的内建对象,稍微归类了一下,多看几遍代码自然笔上生花&#xff…

电脑会显示android,怎么在电脑上显示、操作安卓手机

想要在电脑上显示、操作安卓手机,该怎么办,那么怎么在电脑上显示、操作安卓手机的呢?下面是学习啦小编收集整理的怎么在电脑上显示、操作安卓手机,希望对大家有帮助~~在电脑上显示、操作安卓手机的方法工具/原料windows操作系统安卓手机电脑…

git version是什么软件_Deepin 15.11 安装 ZoneMinder 视频监控软件

Zoneminder是一款开源的视频监控软件,可以很方便的连接ip摄像头。因计划将家中的监控摄像头引入NAS,在一台deepin系统的笔记本是先进行了测试。UBUNTU和debian系统都是很容易安装这个软件的。未来在NAS上用docker启动一个专门的zoneminder,do…

看不出svp补帧_专业补帧软件SVP4 实现PotPlayer视频补帧教程

虽然能实现帧率翻倍,不过现在视频绝大多数都是24帧或25帧,翻倍也才48帧,没办法实现补帧后达到60帧的效果。SVP4是一款专业版视频补帧软件,提供GPU加速,并允许使用中档CPU和几乎任何GPU硬件为60Hz的FullHD 1080p视频重新…

android 通知历史,Android P新特性:追踪应用通知历史

原标题:Android P新特性:追踪应用通知历史IT之家3月9日消息 不久前,谷歌已经正式推出了首个Android P开发者预览版,包含了许多新特性。对此,IT之家也进行了一系列报道。该系统的新特性也正在不断被发现。例如最新消息显…

文件另存为时名称会改变_易经:人处在困境时,不要焦虑,改变固定习惯,就会迎来转机...

我读《易经》,悟到一些规律:人的一生,起起落落,时而顺利,时而受困,都是正常现象,没有必要把困难和压力看得太重。人处在困境时,不要焦虑,只要改变你的固定习惯&#xff0…

ubuntu系统写路由指令_在Ubuntu中如何查看网络路由表详解,

在Ubuntu中如何查看网络路由表详解,什么是Linux中的路由和路由表?路由的过程意味着IP包在网络上从一点传输到另一点。当你向某人发送电子邮件时,你实际上是在将一系列IP数据包或数据报从你的系统传输到另一个人的计算机上。从计算机发送的数据…

jspdf html转换pdf,使用jspdf将HTML转换为pdf时出错

对于一个角度项目,我试图将包含HTML代码的字符串变量转换为pdf文件。我安置了所有的家属,比如:jspdf格式光栅化HTML我的代码如下:b64DecodeUnicode(str) {return decodeURIComponent(atob(str).split().map(function(c) {return % (00 c.charCodeAt(0).toString(16)).slice(-…

澄海哪里学机器人编程_终于发现小孩有必要学机器人编程吗

让孩子学习编程的目的,就像其他教育方式一样,只是希望能帮助孩子找到他的兴趣点,打开孩子的获取知识和能力的大门。一起来看看一篇小孩有必要学机器人编程吗。小孩有必要学机器人编程吗编程和英语类似,属于基本技能,未…

鸿蒙系统替代iOS,华为横空出世!鸿蒙系统,能否替代安卓IOS?

原标题:华为横空出世!鸿蒙系统,能否替代安卓IOS?从长远来看,华为主推鸿蒙系统是必然的选择。毕竟安卓系统为谷歌的,而由于美国限制,让华为格外被动。命运掌握在自己手里,才有足够的话…