Python的深、浅拷贝到底是怎么回事?一篇解决问题
嗨害大家好鸭!我是小熊猫~
一、赋值
Python中,
对象的赋值都是进行对象引用(内存地址)传递,
赋值(=),
就是创建了对象的一个新的引用,
修改其中任意一个变量都会影响到另一个
will = ["Will", 28, ["Python", "C#", "JavaScript"]]
wilber = will #python学习交流裙:660193417
print('will>>', will, id(will))
print('wilber>>', wilber, id(wilber))
print('will的各个元素id>>', [id(ele) for ele in will])
print('wilber的各个元素id>>',[id(ele) for ele in wilber])
print('---'*30)
will[0] = "Wilber"
will[2].append("CSS")
print('will>>', will, id(will))
print('wilber>>', wilber, id(wilber))
print('will的各个元素id>>', [id(ele) for ele in will])
print('wilber的各个元素id>>',[id(ele) for ele in wilber])
#输出为
will>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43988040
wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43988040
will的各个元素id>> [31326928, 493056320, 43988808]
wilber的各个元素id>> [31326928, 493056320, 43988808]
------------------------------------------------------------------------------------------
will>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43988040
wilber>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43988040
will的各个元素id>> [44016672, 493056320, 43988808]
wilber的各个元素id>> [44016672, 493056320, 43988808]
源码资料电子书:点击此处跳转文末名片获取
二、浅拷贝
浅拷贝会创建一个新的对象,
这个例子中”wilber is not will”
但是,
对于对象中的元素,
浅拷贝就只会使用原始元素的引用(内存地址),
也就是说”wilber[i] is will[i]”
当对will
进行修改的时候:
由于list
的第一个元素是不可变类型,
所以will
对应的list
的第一个元素会使用一个新的对象39758496;
但是list的第三个元素是一个可变类型,
修改操作不会产生新的对象,所以will的修改结果会相应的反应到wilber
上
浅拷贝:
创建一个新的对象,
但它包含的是对原始对象中包含项的引用
(如果用引用的方式修改其中一个对象,另外一个也会修改改变)
{1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}
切片也是浅拷贝
import copy
will = ["Will", 28, ["Python", "C#", "JavaScript"]]
wilber = copy.copy(will)
print('will>> ', will, id(will))
print('wilber>> ', wilber, id(wilber))
print('will的各个元素id>> ', [id(ele) for ele in will])
print('wilber的各个元素id>>',[id(ele) for ele in wilber])
print('---'*30)
will[0] = "Wilber"
will[2].append("CSS")
print('will>> ', will, id(will))
print('wilber>> ', wilber, id(wilber))
print('will的各个元素id>> ', [id(ele) for ele in will])
print('wilber的各个元素id>>',[id(ele) for ele in wilber])#输出为
will>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43862024
wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 43861896
will的各个元素id>> [31261392, 493056320, 43862088]
wilber的各个元素id>> [31261392, 493056320, 43862088]
------------------------------------------------------------------------------------------
will>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43862024
wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 43861896
will的各个元素id>> [43886384, 493056320, 43862088]
wilber的各个元素id>> [31261392, 493056320, 43862088]
三、深拷贝
跟浅拷贝类似,深拷贝也会创建一个新的对象,
这个例子中”wilber is not will”
但是,
对于对象中的元素,
深拷贝都会重新生成一份(有特殊情况,下面会说明),
而不是简单的使用原始元素的引用(内存地址)
深拷贝:
创建一个新的对象,
并且递归的复制它所包含的对象
(修改其中一个,另外一个不会改变)
{copy模块的deep.deepcopy()函数}
import copy
will = ["Will", 28, ["Python", "C#", "JavaScript"]]
wilber = copy.deepcopy(will)
print('will>> ', will, id(will))
print('wilber>> ', wilber, id(wilber))
print('will的各个元素id>> ', [id(ele) for ele in will])
print('wilber的各个元素id>>',[id(ele) for ele in wilber])
print('---'*30)
will[0] = "Wilber"
will[2].append("CSS")
print('will>> ', will, id(will))
print('wilber>> ', wilber, id(wilber))
print('will的各个元素id>> ', [id(ele) for ele in will])
print('wilber的各个元素id>>',[id(ele) for ele in wilber])
# 输出为
will>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 37373960
wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 37373832
will的各个元素id>> [31195856, 493056320, 37374024]
wilber的各个元素id>> [31195856, 493056320, 37373768]
------------------------------------------------------------------------------------------
will>> ['Wilber', 28, ['Python', 'C#', 'JavaScript', 'CSS']] 37373960
wilber>> ['Will', 28, ['Python', 'C#', 'JavaScript']] 37373832
will的各个元素id>> [37398264, 493056320, 37374024]
wilber的各个元素id>> [31195856, 493056320, 37373768]
四、特殊情况
对于非容器类型
(如数字、字符串、和其他’原子’类型的对象)
没有拷贝这一说
也就是说,
对于这些类型,
”obj is copy.copy(obj)” 、”obj is copy.deepcopy(obj)”
如果元祖变量只包含原子类型对象,则不能深拷贝,看下面的例子
import copy
books=('a','b','c')
books1,books2 = copy.copy(books),copy.deepcopy(a)
>>books is books1 is books2
# truea = 'python'
b,c = copy.copy(a),copy.deepcopy(a)
In [19]: a is b is c
Out[19]: True
In [20]: id(a),id(b),id(c)
Out[20]: (55466056, 55466056, 55466056)In [30]: t1=('a','b','c',['d'])In [31]: t2,t3 = copy.copy(t1),copy.deepcopy(t1)In [32]: t1 is t2 is t3
Out[32]: FalseIn [33]: id(t1), id(t2), id(t3)
Out[33]: (89247560, 89247560, 88537672)
Python中对象的赋值都是进行对象引用(内存地址)
传递
使用copy.copy(),
可以进行对象的浅拷贝,
它复制了对象,但对于对象中的元素,
依然使用原始的引用.
如果需要复制一个容器对象,
以及它里面的所有元素(包含元素的子元素),
可以使用copy.deepcopy()进行深拷贝
对于非容器类型
(如数字、字符串、和其他’原子’类型的对象)
没有被拷贝一说
如果元祖变量只包含原子类型对象,则不能深拷贝
1.列表的浅拷贝示例
import copy
a = [1,2,3,4,['a','b']] #定义一个列表a
b = a #赋值
c = copy.copy(a) #浅拷贝
d = copy.deepcopy(a) #深拷贝
a.append(5)
a[0] = '10'
print('A0',a,id(a))# [1, 2, 3, 4, ['a', 'b'], 5] #a添加一个元素5
print('B0',b,id(b))
# [1, 2, 3, 4, ['a', 'b'], 5] #b跟着添加一个元素5
print('C0',c,id(c))
# [1, 2, 3, 4, ['a', 'b']] #c保持不变
print('D0',d,id(d))
# [1, 2, 3, 4, ['a', 'b']] #d保持不变
a[4].append('c')
a[4][1]='ASDF'
print('A1',a,id(a))
# [1, 2, 3, 4, ['a', 'b', 'c'], 5] #a中的list(即a[4])添加一个元素c
print('B1',b,id(a))
# [1, 2, 3, 4, ['a', 'b', 'c'], 5] #b跟着添加一个元素c
print('C1',c,id(c))
# [1, 2, 3, 4, ['a', 'b', 'c']] #c跟着添加一个元素c
print('D1',d,id(d))
[1, 2, 3, 4, ['a', 'b']] #d保持不变
2.单个列表的copy
names = ['alex','jack','1','mack','racheal','shanshan']
n2 = names
n3 = names.copy()
n4 = names[:]print('第一轮','names',names,id(names))
print('第一轮','n2',n2,id(n2))
print('第一轮','n3',n3,id(n3))
print('第一轮','n4',n4,id(n4))names.append('hery')
names[0]="Alex"
print('第二轮','names',names,id(names))
print('第二轮','n2',n2,id(n2))
print('第二轮','n3',n3,id(n3))
print('第二轮','n4',n4,id(n4))
输出:
第一轮 names ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167690376
第一轮 n2 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167690376
第一轮 n3 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167692616
第一轮 n4 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167713928
第二轮 names ['Alex', 'jack', '1', 'mack', 'racheal', 'shanshan', 'hery'] 167690376
第二轮 n2 ['Alex', 'jack', '1', 'mack', 'racheal', 'shanshan', 'hery'] 167690376
第二轮 n3 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167692616
第二轮 n4 ['alex', 'jack', '1', 'mack', 'racheal', 'shanshan'] 167713928
3.字符串的copy
import copy
name="hahah" #字符串
name1=copy.copy(name)
name2=copy.deepcopy(name)
print('第一次',id(name),id(name1),id(name2))sum=111 #数字
sum1=copy.copy(sum)
sum2=copy.deepcopy(sum)
print('第二次',id(sum),id(sum1),id(sum2))
输出:
第一次 31179752 31179752 31179752
第二次 1702001568 1702001568 1702001568
4.字典的copy
import copy
call = {'cpu':[80,25],'mem':[80,],'disk':[80,]
}
new_call_1 = copy.copy(call)
new_call_2 = copy.deepcopy(call)
print('修改前call1为:%s' %(call),id(call))
# #修改新模版
call['disk'] = 66
call['disk_2'] = 67
call['cpu'].append(20)
call['cpu'][1]=11
new_call_1['cpu'].append(33)
new_call_1['disk'][0] = 77
new_call_1['mem'] = 75
new_call_2['disk'][0] = 79
# #查看新旧模版的值
print('call1为:%s' %(call),id(call))
print('new_call_1为:%s' %(new_call_1),id(new_call_1))
print('new_call_2为:%s' %(new_call_2),id(new_call_2))
输出:
修改前call1为:{'cpu': [80, 25], 'mem': [80], 'disk': [80]} 4411328
call1为:{'cpu': [80, 11, 20, 33], 'mem': [80], 'disk': 66, 'disk_2': 67} 4411328
new_call_1为:{'cpu': [80, 11, 20, 33], 'mem': 75, 'disk': [77]} 4452424
new_call_2为:{'cpu': [80, 25], 'mem': [80], 'disk': [79]} 31977616
Python 打印进度条
import time
for i in range(0,101,2):time.sleep(0.1)char_num = i//2 #打印多少个'*'per_str = '\r%s%% : %s\n' % (i, '>>>' * char_num) if i == 100 else '\r%s%% : %s'%(i,'*'*char_num)print(per_str,end='', flush=True)
相关文章:
Python的深、浅拷贝到底是怎么回事?一篇解决问题
嗨害大家好鸭!我是小熊猫~ 一、赋值 Python中, 对象的赋值都是进行对象引用(内存地址)传递, 赋值(), 就是创建了对象的一个新的引用, 修改其中任意一个变量都会影响到另一个 will …...
TCP协议十大特性
日升时奋斗,日落时自省 目录 1、确认应答 1.1、序号编辑 2、超时重传 3、连接管理 3.1、三次握手 3.2、四次挥手 4、滑动窗口 5、流量控制 6、拥塞控制 7、延时应答 8、捎带应答 9、面向字节流 10、异常情况 TCP协议: 特点:有…...
2.14作业【GPIIO控制LED】
设备树 myleds{ myled1 <&gpioe 10 0>; myled2 <&gpiof 10 0>; myled3 <&gpioe 8 0>; }; 驱动代码 #include<linux/init.h> #include<linux/module.h> #include<linux/of.h&…...
5min搞定linux环境Jenkins的安装
5min搞定linux环境Jenkins的安装 安装Jenkinsstep1: 使用wget 命令下载Jenkinsstep2、创建Jenkins日志目录并运行jekinsstep3、访问jenkins并解锁jenkins,安装插件以及创建管理员用户step4、到此,就完成了Finish、以上步骤中遇到的问题1、 jenkins启动不了2、jenkins无法访问…...
Cortex-M0存储器系统
目录1.概述2.存储器映射3.程序存储器、Boot Loader和存储器重映射4.数据存储器5.支持小端和大端数据类型数据对齐访问非法地址多寄存器加载和存储指令的使用6.存储器属性1.概述 Cortex-M0处理器具有32位系统总线接口,以及32位地址线(4GB的地址空间&…...
软件测试——测试用例之场景法
一、场景法的应用场合 场景法主要用于测试软件的业务流程和业务逻辑。场景法是基于软件业务的测试方法。在场景法中测试人员把自己当成最终用户,尽可能真实的模拟用户在使用此软件的操作情景: 重点模拟两类操作: 1)模拟用户正确…...
英文写作中的常用的衔接词
1. 增补 (Addition) in addition, furthermore, again, also, besides, moreover, whats more, similarly, next, finally 2.比较(Comparision) in the same way, similarly, equally, in comparison, just as 3. 对照 (Contrast) in contrast, on …...
新库上线 | CnOpenData中国地方政府债券信息数据
中国地方政府债券信息数据 一、数据简介 地方政府债券 指某一国家中有财政收入的地方政府地方公共机构发行的债券。地方政府债券一般用于交通、通讯、住宅、教育、医院和污水处理系统等地方性公共设施的建设。地方政府债券一般也是以当地政府的税收能力作为还本付息的担保。地…...
Python 条件语句
Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false。 Python 编…...
C语言思维导图大总结 可用于期末考试 C语言期末考试题库
目录 一.C语言思维导图 二.C语言期末考试题库 一.C语言思维导图 导出的图可能有点糊,或者查看链接:https://share.weiyun.com/uhf1y2mp 其实原图是彩色的不知道为什么导出时颜色就没了 部分原图: 也可私信我要全图哦。 图里的链接可能点不…...
从零实现深度学习框架——再探多层双向RNN的实现
来源:投稿 作者:175 编辑:学姐 往期内容: 从零实现深度学习框架1:RNN从理论到实战(理论篇) 从零实现深度学习框架2:RNN从理论到实战(实战篇) 从零实现深度…...
Flink 连接流详解
连接流 1 Union 最简单的合流操作,就是直接将多条流合在一起,叫作流的“联合”(union)。联合操作要求必须流中的数据类型必须相同,合并之后的新流会包括所有流中的元素,数据类型不变。这种合流方式非常简…...
分享112个HTML电子商务模板,总有一款适合您
分享112个HTML电子商务模板,总有一款适合您 112个HTML电子商务模板下载链接:https://pan.baidu.com/s/13wf9C9NtaJz67ZqwQyo74w?pwdzt4a 提取码:zt4a Python采集代码下载链接:采集代码.zip - 蓝奏云 有机蔬菜水果食品商城网…...
2023备战金三银四,Python自动化软件测试面试宝典合集(八)
马上就又到了程序员们躁动不安,蠢蠢欲动的季节~这不,金三银四已然到了家门口,元宵节一过后台就有不少人问我:现在外边大厂面试都问啥想去大厂又怕面试挂面试应该怎么准备测试开发前景如何面试,一个程序员成长之路永恒绕…...
J-Link RTT Viewer使用教程(附代码)
目录 RTT(Real Time Transfer)简介 使用教程 常用API介绍 RTT缓冲大小修改 使用printf重定向 官方例程 RTT(Real Time Transfer)简介 平常调试代码中使用串口打印log,往往需要接出串口引脚,比较麻烦,并且串口打印速度较慢,串…...
C语言——指针、数组的经典笔试题目
文章目录前言1.一维数组2.字符数组3.二维数组4.经典指针试题前言 1、数组名通常表示首元素地址,sizeof(数组名)和&数组名两种情况下,数组名表示整个数组。 2、地址在内存中唯一标识一块空间,大小是4/8字节。32位平台4字节,64位…...
【C语言】程序环境和预处理|预处理详解|定义宏(上)
主页:114514的代码大冒险 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、程序的翻译环境和执行环境 二、详解编译和链接 1.翻译环境 2.编…...
上海霄腾自动化装备盛装亮相2023生物发酵展
上海霄腾自动化携液体膏体粉剂颗粒等灌装生产线解决方案亮相2023生物发酵展BIO CHINA2023生物发酵展,作为生物发酵产业一年一度行业盛会,由中国生物发酵产业协会主办,上海信世展览服务有限公司承办,2023第10届国际生物发酵产品与技…...
python+flask开发mock服务
目录 什么是mock? 什么时候需要用到mock? 如何实现? pythonflask自定义mock服务的步骤 一、环境搭建 1、安装flask插件 2、验证插件 二、mock案例 1、模拟 返回结果 2、模拟 异常响应状态码 3、模拟登录,从jmeter中获取…...
数据库(三)
第三章 MySQL库表操作 3.1 SQL语句基础 3.1.1 SQL简介 SQL:结构化查询语言(Structured Query Language),在关系型数据库上执行数据操作、数据检索以及数据维护的标准语言。使用SQL语句,程序员和数据库管理员可以完成如下的任务。 改变数据…...
2023软考纸质证书领取通知来了!
不少同学都在关注2022下半年软考证书领取时间,截止至目前,上海、湖北、江苏、南京、安徽、山东、浙江、宁波、江西、贵州、云南、辽宁、大连、吉林、广西地区的纸质证书可以领取了。将持续更新2022下半年软考纸质证书领取时间,请同学们在证书…...
Python requests模块
一、requests模块简介 requests模块是一个第三方模块,需要在python环境中安装: pip install requests 该模块主要用来发送 HTTP 请求,requests 模块比 urllib 模块更简洁。 requests模块支持: 自动处理url编码自动处理post请求…...
工业智能网关解决方案:物联网仓储环境监测系统
仓储是连接生产、供应和销售的中转系统,对于促进生产、提高效率有着重要的辅助作用。对于很多大型工厂或食品厂来说,需要对仓储环境进行严控的控制,以确保产品或食品的质量,避免不必要的产品损耗,提高产品存管的水平。…...
Linux进程线程管理
目录 存储管理 linux内存管理基本框架 系统空间管理和用户空间管理 进程与进程调度 进程四要素 用户堆栈的扩展 进程三部曲:创建,执行,消亡 系统调用exit(),wait() 内核中的互斥操作 存储管理 linux内存管理基本框架 系统空间管理…...
分享111个HTML电子商务模板,总有一款适合您
分享111个HTML电子商务模板,总有一款适合您 111个HTML电子商务模板下载链接:https://pan.baidu.com/s/1e8Wp1Rl9RaFrcW0bilIatg?pwdc97h 提取码:c97h Python采集代码下载链接:采集代码.zip - 蓝奏云 HTML5家居家具电子商务网…...
百度前端必会手写面试题整理
请实现一个 add 函数,满足以下功能 add(1); // 1 add(1)(2); // 3 add(1)(2)(3);// 6 add(1)(2, 3); // 6 add(1, 2)(3); // 6 add(1, 2, 3); // 6function add(...args) {// 在内部声明一个函数,利用闭包的特性保存并收集…...
ubuntu 安装支持GPU的Docker详细步骤
安装依赖项 sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common 添加 Docker GPG 密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo apt-key fingerpr…...
usbmon+tcpdump+wireshark USB抓包
文章目录usbmon抓包及配合wireshark解析usbmon抓包及配合wireshark解析 usbmon首先编译为内核模块,然后通过modprobe usbmon加载到linux sys文件系统中 rootroot-PC:~# modprobe usbmon 而后 linux系统下安装 tcpdump rootroot-PC:~# apt-get install tcpdump…...
【LeetCode】剑指 Offer 04. 二维数组中的查找 p44 -- Java Version
题目链接: https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/ 1. 题目介绍(04. 二维数组中的查找) 在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递…...
TDengine 3.0.2.5 查询再优化!揭秘索引文件的工作原理
TDengine 3.0 虽然对底层做了大规模的优化重构,但是相对于数据文件的工作逻辑和 2.0 相比是整体保持不变的。本系列文章的主旨在于帮助用户深入理解产品,并且拥有基本的性能调试思路,从而获得更好的产品体验。本期文章会在讲解 TDengine 时序…...
网架加工制造厂家/seosem顾问
vue3手写电商微信小程序( 微信开发者工具)【问题总结】该项目技术栈:vite3 vue3.2 pinia typeScript1、样式穿透在微信开发者工具不适用:2、v-html在微信开发者工具显示的是rich-text组件,导致样式不适用࿱…...
湖南网站建设多少钱/销售
大家知道Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。其中有些区域随着虚拟机进程的启动而存在,而有些区域则依赖用户线程的启动和结束而建立和销毁。…...
wordpress免费版/重庆网站seo教程
golang笔记06--golang 面向接口1 介绍2 面向接口2.1 接口的概念2.2 duck typing的概念2.3 接口的定义和实现2.4 接口的值类型2.5 接口的组合2.6 常用系统接口3 注意事项4 说明1 介绍 本文继上文 golang笔记05–go语言的依赖管理, 进一步了解 go语言的面向接口特性和…...
建设一个网站怎么赚钱/网站推广是做什么的
6.1 概述 创建每个过程时,应该假设它可能出现错误 ( 一 ) 错误来源: 编程员 环境方面(磁盘空间) 时间(未加载完毕) ( 二 ) 错误分类: 1 、编译 例如: 定义: Public sub MyProcedure(intMyVariable As Integer) 调用&am…...
永久免费手机建站平台/小程序开发哪家更靠谱
gin框架18--将 request body 绑定到不同的结构体中介绍案例说明介绍 本文主要介绍如何将 request body 绑定到不同的结构体中,并加以案例说明。 案例 案例1: 使用 c.ShouldBind, 但不可重用 package mainimport ("github.com/gin-go…...
柳州在哪里做网站/上海哪家seo好
春天到来前,5G正在准备搞点大事情。就在前两天,特朗普又专门为5G发推特,强调美国要尽快发展5G,并且强调要靠竞争而不是封杀来发展技术。这里咱们放下特朗普的内心戏暂且不表,至少美国总统频频发声,证明了5G…...