python之路(三)-深浅拷贝
深浅拷贝用法来自copy模块。
导入模块:import copy
浅拷贝:copy.copy
深拷贝:deepcopy
字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层。所以对于只有一层的数据集合来说深浅拷贝的意义是一样的,比如字符串,数字,还有仅仅一层的字典、列表、元祖等
对于以下数据深浅拷贝的意义是一样的:
name = 'beijing'
age = 12
list1 = [1,2,3,4]
dic1 = {'name':'beijing','age':20}
以上数据类型中只有一层,所以深浅拷贝是一样的。
从内存地址来理解深浅拷贝:
浅拷贝:
字符串,数字的深浅拷贝
如上图,对于数字和字符串的深浅拷贝都只是将变量的索引指向了原来的内存地址,例如在num,num1,num2三个变量中,无论修改任意其中一个变量,只是将其指向了另一个内存地址,其他两个变量不会变,字符串同理。
因此,对于 数字 和 字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。
字典(列表)的深浅拷贝
赋值:
import copy
n1 = {'k1':'wu','k2':123,'k3':['alex',678]}
n2 = n1
浅拷贝:
import copy
n1 = {'k1':'wu','k2':123,'k3':['alex',678]}
n2 = copy.copy(n1)
深拷贝:
import copy
n1 = {'k1':'wu','k2':123,'k3':['alex',678]}
n3 = copy.deepcopy(n1)
深浅拷贝的应用场景
比如在CMDB系统中,我们定义了一个报警模版call给所有的服务器使用,此时有一批特殊应用的服务器需要不通的报警参数,我们既不想单独新建模版来一个一个添加报警参数,又不想修改默认模版而影响其他机器的报警阈值。此时我们就需要用深拷贝来完成。示例如下:
默认模版:
call = {
'cpu':80,
'mem':80,
'disk':80
}
此时的特殊模版需求是cpu报警阀值要改成75,而不影响默认模版使用
代码如下:
#默认模版
call = {
'cpu':[80,],
'mem':[80,],
'disk':[80,]
} #新模板
new_call = copy.deepcopy(call)
#修改新模版
new_call['cpu'] = 75
#查看新旧模版的值
print('新的模版为:%s' %(new_call))
print('默认模版为:%s' %(call)) #打印结果:
新的模版为:{'mem': 80, 'disk': 80, 'cpu': 75}
默认模版为:{'mem': 80, 'disk': 80, 'cpu': 80} #上面的代码显示我们只改了新的模版,而默认模版并没有修改,并且我们用了copy而不是单独新建模版。
假设我们用浅copy来做结果是这样的:
#默认模版
call = {
'cpu':[80,],
'mem':[80,],
'disk':[80,]
} #新模板
new_call = copy.deepcopy(call)
#修改新模版
new_call['cpu'] = 75
#查看新旧模版的值
print('新的模版为:%s' %(new_call))
print('默认模版为:%s' %(call))
#打印的结果:
新的模版为:{'mem': [80], 'disk': [80], 'cpu': [75]}
默认模版为:{'mem': [80], 'disk': [80], 'cpu': [75]} #默认模版和新模版都被修改了,显然这不是我们要的结果
分析原因:深拷贝的时候python将字典的所有数据在内存中新建了一份,所以如果你修改新的模版的时候老模版不会变。相反,在浅copy 的时候,python仅仅将最外层的内容在内存中新建了一份出来,字典第二层的列表并没有在内存中新建,所以你修改了新模版,默认模版也被修改了。
注:深copy并没有在内存中新建列表中的元素,因为上例中列表的元素是数字,这得益于python对数字和字符串的优化机制,即,若字符串或者数字没有修改,它的内存位置永远不变,直到它被修改。
python之路(三)-深浅拷贝的更多相关文章
- python学习笔记:深浅拷贝的使用和原理
在理解深浅拷贝之前,我们先熟悉下变量对象和数据类型 1.变量和对象 变量-引用-对象(可变对象,不可变对象) 在python中一切都是对象,比如[1,2],'hello world',123,{'k1 ...
- python变量存储和深浅拷贝
python的变量及其存储 在高级语言中,变量是对内存及其地址的抽象.对于python而言,python的一切变量都是对象,变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不 ...
- python set集合 以及 深浅拷贝
set集合 特点: 无序, 不重复, 元素必须可哈希(不可变) 作用: 去重复 本身是可变的数据类型. 有增删改查操作. frozenset()冻结的集合. 不可变的. 可hash的 深浅拷贝() 1 ...
- python直接赋值、深浅拷贝实例剖析
根据数据类型分为两部分进行剖析: int.str类型 list.tuple.dict类型等 1. int.str类型 [int类型实例] >>> import copy ...
- python内存相关以及深浅拷贝讲解
3.9 内存相关 3.9.1 id,查看内存地址 >>> v1 = [11,22,33] >>> v2 = [11,22,33] >>> prin ...
- Python collection模块与深浅拷贝
collection模块是对Python的通用内置容器:字典.列表.元组和集合的扩展,它包含一些专业的容器数据类型: Counter(计数器):dict子类,用于计算可哈希性对象的个数. Ordere ...
- Python基础入门知识点——深浅拷贝
深浅拷贝 对象引用.浅拷贝.深拷贝(拓展.难点.重点) Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果 其实这个是由于共享内存导致的结果 拷贝 ...
- 从零开始的Python学习Episode 8——深浅拷贝
深浅拷贝 一.浅拷贝 列表中存储的是数据的内存地址,当我们要查询或修改列表中的数据时,我们是通过列表中的地址找到要访问的内存.当我们修改列表中的数据时,如果修改的是一个不可变类型(整型,长整型,浮点数 ...
- python神坑系列之深浅拷贝
深浅拷贝 1.注意在拷贝中只有使用了.deepcopy方法才能进行深度拷贝!其余的一律是浅拷贝 #深拷贝import copy lst = copy.deepcopy(lst1) 浅拷贝: 拷贝的是 ...
随机推荐
- 《算法导论》——计数排序Counting Sort
今天贴出的算法是计数排序Counting Sort.在经过一番挣扎之前,我很纠结,今天这个算法在一些scenarios,并不是最优的算法.最坏情况和最好情况下,时间复杂度差距很大. 代码Countin ...
- 调整iframe滚动条失效
1:<iframe scrolling="auto" frameborder="0" src="' + add + '" style= ...
- Github使用笔记——创建远程库
系统:CentOS7 一.yum install git 二.配置 git config --global user.name "XXX" git config -global u ...
- 操作系统切换CPU的方式
操作系统切换CPU的方式 1 IO等待切换. 2 时间轮询切换,也就是如果没有IO等待的情况下,就会有时间轮询切换,不让CPU一直处理一个任务 CPU的处理速度是纳秒级别的,所有我们可以同时听歌, ...
- phpstudy+dvwa配置
1.Apache端口被系统进程占用(Pid一般为4) -- 修改apache端口,然后通过localhost:端口号访问 2.DVWA System error - config file not f ...
- Java入门到精通第4版汇总
- Itellj Idea使用技巧
模板设置: 类模板:File–>Settings–>Editor–>File and Code Templates–>Includes–>File Header 输入缩写 ...
- mysql 使用注意
1. consider upgrading MySQL client 描述:因mysql5版本过度到8版本后,访问要求升级mysql的客户端 原因:mysql在升级后,对加密算法部分做了调整导致. 对 ...
- python中os模块
os 模块 操作系统模块,该模块主要处理与操作系统相关的操作 最常用是文件操作:打开.读取 import os os.getcwd() #获取当前执行文件夹路径 os.chdir('dirnam ...
- [INet] WebSocket 数据收发的详细过程
WebSocket 和 HTTP 相似,只是一个应用层协议,对下层透明,所以不涉及 TCP/IP. 由于浏览器支持了 WebSocket,所以在用 JS 写客户端的时候,是无需考虑数据的编码解码的. ...