Python中复制、深拷贝和浅拷贝的区别
深拷贝定义(deepcopy)
在Python中,由于一切皆对象,所以任何变量都可以被引用,也即可以被赋值给任何变量。但是在Python中,给变量赋值,是区分的,一般情况下,Python中的变量赋值都是浅拷贝,如果需要使用深拷贝,需要特别指定。
深拷贝是对原对象的“复制以及粘贴”,其实就是在内存中重新开辟了一个新的内存空间来存放这一份数据,两个变量其实是两个不一样的变量,仅仅是数据值相同而已,对两个变量的操作不会相互影响。
浅拷贝(copy)
在Python中进行数据的浅拷贝时,如果此时浅拷贝的数据是Python中的原子数据结构,比如str,int,float,tuple等不可变的原子数据结构,那么在Python解释器中,会给新赋值的变量开辟一个新的内存空间,且新的内存空间中存放的值和浅拷贝的数据值一致。
例如:

此时需要注意,Python中如果int数值小于一定的数的话,Python还是会引用同一个数据值,也就是a和b两个变量的地址一样。如:

且当改变a和b的数值时,地址也会发生改变,就相当于是a和b都是两个指针,指向具体的存放数值的地址空间,如果修改完后a和b的数值一致,那么a和b的地址也会一样。如:

当对一些可变对象进行浅拷贝时,此时其实是对可变对象的二次引用,并没有重新开辟新的内存空间。如:

从图中可以看到,a和b都是对列表的引用,虽然a是先引用的该列表,但是他们在内存中的地址都是一样的,也就是说他们其实是同一个列表的两个不同的昵称而已。
列表的两种不同的赋值方式,“=”和切片操作,它们之间的区别如下:
“=”:该符号对于浅拷贝而言,其实就是将“=”两边的两个不同的变量同时指向了同一个内存空间,且内存空间的值是相同的。当一个变量对内存空间中的数值进行了修改之后,在使用另一个变量去引用该内存空间中的变量时,数值也会改变,因为他们都指向同一个数据值。
切片操作:当时切片操作(a[start_index:end_index])对一个列表进行赋值给另外一个变量时,这时不再是两个不同的变量同时指向一个内存地址空间中数据值,因为切片操作会返回一个新的列表,所以新的变量会接收一个新的列表,新的列表中的数据值就是切片之后的数据值,且在内存中的地址空间不一样。如图:

此时对c的任何操作与a(b)无关,因为a和b其实是同一个列表。
但是当列表中有可变数据结构时(list,dict等)就会出现不一样的结果,因为在Python中,对于可变的数据类型,Python解释器会给变量采用引用的方式对 可变的数据类型的数据 进行引用,为了节省内存空间。 如图所示:

如果需要让两个变量能同时且独立的操作该列表(列表中有可变的数据类型的数据),那么就需要使用到深拷贝对数据进行直接到拷贝,而不是引用。此时需要使用到一个Python中的内书库函数copy,copy库中的deepcopy()方法可以对数据进行直接到拷贝(深拷贝),如图所示:

从图中可以看到,c是对a的深拷贝,b是对a的切片操作的浅拷贝,同时修改列表中的可变元素,可见c中的数据是存放在一个独立的内存空间中的。
在Python对数据对象进行拷贝时,需要注意:



Python中复制、深拷贝和浅拷贝的区别的更多相关文章
- **Python中的深拷贝和浅拷贝详解
Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要 ...
- python中的深拷贝和浅拷贝
python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...
- 001 说说Python中的深拷贝和浅拷贝
在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
- python中的深拷贝与浅拷贝
深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...
- python中的深拷贝和浅拷贝理解
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用.以下分两个思路来分别理解浅拷贝和深拷贝: 利用切 ...
- python学习笔记--深拷贝与浅拷贝的区别
首先我们来讲讲我们python中的可变对象和不可变对象: 可变对象:该对象指向内存中的值是可以改变的.实际上是其所指的值直接发生改变,而不是发生复制,或者开辟一个新的地址空间.例如:列表list,字典 ...
- Python 中的深拷贝和浅拷贝
一.浅拷贝python中 对象赋值时 默认是浅拷贝,满足如下规律:1. 对于 不可变对象(字符串,元组 等),赋值 实际上是创建一个新的对象:例如: >>> person=['nam ...
- python赋值,深拷贝和浅拷贝的区别
1.赋值 list1=[[1,2],'fei',66] list2=list1 list1 [[1, 2], 'fei', 66] list2 [[1, 2], 'fei', 66] list2.ap ...
- python中的深拷贝和浅拷贝(面试题二)
一.浅拷贝 定义:浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值. 浅拷贝的特点: 公用一个值: 这两个变量的内存地址一样: 对其中一个变量的值改变,另外一个变量的值也 ...
随机推荐
- 微信小程序-滑动视图注意事项
真的得吐槽下微信的开发文档,一点点都不详细的好吗. <!--垂直滚动,这里必须设置高度--> <scroll-view scroll-y="true" style ...
- 如何用Python实现常见机器学习算法-4
四.SVM支持向量机 1.代价函数 在逻辑回归中,我们的代价为: 其中: 如图所示,如果y=1,cost代价函数如图所示 我们想让,即z>>0,这样的话cost代价函数才会趋于最小(这正是 ...
- mongo学习-TTL索引 过期数据
在mongo中我们可以设置文档的过期时间,超过时间,文档会自动删除.(2.x版本中 固定结合也支持,但是到了3.x中 固定集合这个索引不好用) 用法: 1.创建一个db:db.createColle ...
- BASE64Encoder及BASE64Decoder编译器找不到问题
编译器自带这两个类,但是会报错找不到,需要手动让编译器识别这个类 第一步.右键项目,然后选择properties 第二步,打开如图位置 第三部,选择如图位置,双击 第四部,add添加 更改值 改为如图 ...
- 企业搜索引擎开发之连接器connector(十九)
连接器是基于http协议通过推模式(push)向数据接收服务端推送数据,即xmlfeed格式数据(xml格式),其发送数据接口命名为Pusher Pusher接口定义了与发送数据相关的方法 publi ...
- 5、Docker架构和底层技术
5.1 Docker Platform Docker提供了一个开发,打包,运行APP的平台 把APP和底层infrastructure隔离开来 5.2 Docker Engine 后台进程(docke ...
- 20145233计算机病毒实践九之IDA的使用
20145233计算机病毒实践之IDA的使用 PSLIST导出函数做了什么 这个函数是一个export函数,所以在view中选择export 查到后,双击打开这个函数的位置 仔细看这个函数可以发现这个 ...
- Javascript设计模式理论与实战:组合模式
我们平时开发过程中,一定会遇到这种情况:同时处理简单对象和由简单对象组成的复杂对象,这些简单对象和复杂对象会组合成树形结构,在客户端对其处理的时候要保持一致性.比如电商网站中的产品订单,每一张产品订单 ...
- 模拟远程HTTP的POST请求
建立请求,以模拟远程HTTP的POST请求方式构造并获取处理结果 /// <summary> /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取处理结果 /// </s ...
- 微信小程序开发中的二三事之网易云信IMSDK DEMO
本文由作者邹永胜授权网易云社区发布. 简介 为了更好的展示我们即时通讯SDK强悍的能力,网易云信IM SDK微信小程序DEMO的开发就提上了日程.用产品的话说就是: 云信 IM 小程序 SDK 的能力 ...