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中的深拷贝和浅拷贝(面试题二)
一.浅拷贝 定义:浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值. 浅拷贝的特点: 公用一个值: 这两个变量的内存地址一样: 对其中一个变量的值改变,另外一个变量的值也 ...
随机推荐
- Emacs中编辑保存makefile文件时会错误地将TAB转成空格的解决方法
问题描述 我的Emacs使用了Purcell的配置,在其配置中使用了whitespace-cleanup,且通过在.emacs.d/lisp/init-edit-utils.el中设定: (requi ...
- thinkphp 3.2.3 addAll方法的坑
在批量插入一组数据的时候,总是提示以下错误 Insert value list does not match column list: Column count doesn't match value ...
- DSO(dsoframer)的接口文档
(开发环境)使用前先注册一下DSOFramer.ocx 操作:将DSOFramer.ocx复制到C:\windows\system32目录下, 开始->运行->reg ...
- 关于Yii2.0的url路径优化问题(配置虚拟路径)
backend/config/main.php 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => fa ...
- mysql导出导入sql文件方法(linux)
一.导入导出.sql文件for Linux: 1.从mysql中导出数据库test: 在终端运行:mysqldump -h localhost -u root -p test > /home/c ...
- Work at a KFC fast food restaurant
During the summer holiday of 2005,I thought I should do some meaningful instead of at home and watch ...
- c# Brush、Color、String相互转换
using System.Windows.Media; 1.String转换成Color Color color = (Color)ColorConverter.ConvertFromString(s ...
- 深海划水队项目---七天冲刺day1
团队会议: 团队成员的任务认领安排: 张兆敏:登录界面,游戏界面(包含游戏区.控制区.显示信息区). 乐滔:方块的形状.移动(向左或者向右)旋转(顺时针或者逆时针),方块的下落(包含硬着陆和软着陆), ...
- Oracle EBS Request Status: Pending
如果提交请求以后,状态一直是pending状态,可以在"工具"打开"Manager",查看一下Maximum是否有设置错,另外pending的数量当前是多少. ...
- 为已经存在的TFS团队项目配置SharePoint集成
配置好TFS团队项目集合与SharePoint站点集的集成后,就可以在新建TFS团队项目时集成SharePoint站点,也可以为已经存在的团队项目配置SharePoint站点的集成,如下图: Fi ...