深拷贝定义(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对数据对象进行拷贝时,需要注意:

第一、非容器类型(比如数字、字符串和其它“原子”类型的对象,像代码、类型和range对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成。
第二、如果元组变量中只包含原子类型对象,对它的深拷贝将不会进行。
从图中可以看到,tuple中都是“原子”类型的数据对象,此时对其进行深拷贝,但是查看内存中的地址,并没有给b重新开辟一个新的内存空间,所以需要注意这一点。
但是如果tuple有可变的数据类型的对象时,深拷贝是起作用的。
----------------------------------------------------------------------------------
如果您觉得我的博客对您有一定的帮助,可以给我一点点的鼓励,您的鼓励是对我的最大的肯定,我会继续努力。谢谢您。
 支付宝:                                      微信支付:
      
 

Python中复制、深拷贝和浅拷贝的区别的更多相关文章

  1. **Python中的深拷贝和浅拷贝详解

    Python中的深拷贝和浅拷贝详解   这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容.   要说清楚Python中的深浅拷贝,需要 ...

  2. python中的深拷贝和浅拷贝

    python的复制,深拷贝和浅拷贝的区别   在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...

  3. 001 说说Python中的深拷贝和浅拷贝

    在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...

  4. Python赋值语句与深拷贝、浅拷贝的区别

    参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...

  5. python中的深拷贝与浅拷贝

    深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...

  6. python中的深拷贝和浅拷贝理解

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用.以下分两个思路来分别理解浅拷贝和深拷贝: 利用切 ...

  7. python学习笔记--深拷贝与浅拷贝的区别

    首先我们来讲讲我们python中的可变对象和不可变对象: 可变对象:该对象指向内存中的值是可以改变的.实际上是其所指的值直接发生改变,而不是发生复制,或者开辟一个新的地址空间.例如:列表list,字典 ...

  8. Python 中的深拷贝和浅拷贝

    一.浅拷贝python中 对象赋值时 默认是浅拷贝,满足如下规律:1. 对于 不可变对象(字符串,元组 等),赋值 实际上是创建一个新的对象:例如: >>> person=['nam ...

  9. python赋值,深拷贝和浅拷贝的区别

    1.赋值 list1=[[1,2],'fei',66] list2=list1 list1 [[1, 2], 'fei', 66] list2 [[1, 2], 'fei', 66] list2.ap ...

  10. python中的深拷贝和浅拷贝(面试题二)

    一.浅拷贝 定义:浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值. 浅拷贝的特点: 公用一个值: 这两个变量的内存地址一样: 对其中一个变量的值改变,另外一个变量的值也 ...

随机推荐

  1. was not registered for synchronization because synchronization is not active

    报SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7862f70e] was not registered for s ...

  2. Qt Customize QVariant

    Customize QVariant #include <QCoreApplication> #include <QVariant> #include <QDebug&g ...

  3. JetBrains全家桶激活地址

    全家桶地址:https://www.jetbrains.com/products.html?fromMenu JetBrains 授权服务器(License Server URL):http://id ...

  4. Ubuntu在命令行下将默认语言改为英语

    将Ubuntu安装成中文版,需要将默认语言改为英文. 用vi(或nano等文本编辑器)打开 /etc/default/locale 文件 将原来的配置内容修改为 LANG=”en_US.UTF-8″ ...

  5. Disruptor 系列(一)快速入门

    Disruptor 系列(一)快速入门 Disruptor:是一个开源的并发框架,能够在 无锁 的情况下实现网络的 Queue 并发操作,所以处理数据的能力比 Java 本身提供的并发类容器要大的多, ...

  6. CodeForces 513A Game (水题,博弈)

    题意:两个人有n1,n2个球,然后分别最多拿出 k1,k2个球,然后扔掉,谁先拿完谁输. 析:很简单么,每人都足够聪明,就每次扔一个好了,那么,谁的球多,谁就能赢呗,如果相等,那么第一个扔的输. 代码 ...

  7. div模拟键盘输入

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  8. dojo表格操作的简单示例(建立表格)

    代码示例: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w ...

  9. 命令行传递参数并排序 AS实现加法

    题目:从命令行输入参数并进行排序 1.实验准备 Integer提供了能在 int 类型和 String 类型之间互相转换的方法,还提供了处理 int 类型时非常有用的其他一些常量和方法. static ...

  10. c++ vector反转reverse

    template <class BidirectionalIterator> void reverse ( BidirectionalIterator first, Bidirection ...