一、赋值

>>> a = [1, 2, 3]
>>> b = a
>>> print(id(a), id(b), sep='\n')
139701469405552
139701469405552

注:id()函数返回对象的内存地址
在Python中,用一个变量给另一个变量赋值,其实就是给当前内存中的对象增加一个“标签”而已。如上例,通过使用内置函数 id() ,可以看出 a 和 b 指向内存中同一个对象。a is b会返回 True。

二、、浅拷贝(shallow copy)

注意:浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。

所谓“浅拷贝”,是指创建一个新的对象,其内容是原对象中元素的引用。(拷贝组合对象,不拷贝子对象)。常见的浅拷贝有:切片操作、工厂函数、对象的copy()方法、copy模块中的copy函数。

>>> a = [1, 2, 3]
>>> b = list(a)
>>> print(id(a), id(b))          # a和b身份不同
140601785066200 140601784764968
>>> for x, y in zip(a, b):       # 但它们包含的子对象身份相同
...     print(id(x), id(y))
...
140601911441984 140601911441984
140601911442016 140601911442016
140601911442048 140601911442048

从上面可以明显的看出来,a 浅拷贝得到 b,a 和 b 指向内存中不同的 list 对象,但它们的元素却指向相同的 int 对象。这就是浅拷贝

三、深拷贝(deep copy)

所谓“深拷贝”,是指创建一个新的对象,然后递归的拷贝原对象所包含的子对象。深拷贝出来的对象与原对象没有任何关联。深拷贝只有一种方式:copy模块中的deepcopy函数

为什么使用了深拷贝,a和b中元素的id还是一样呢?

答:这是因为对于不可变对象,当需要一个新的对象时,python可能会返回已经存在的某个类型和值都一致的对象的引用。而且这种机制并不会影响 a 和 b 的相互独立性,因为当两个元素指向同一个不可变对象时,对其中一个赋值不会影响另外一个。

我们可以用一个包含可变对象的列表来确切地展示“浅拷贝”与“深拷贝”的区别:

>>> import copy
>>> a = [[1, 2],[5, 6], [8, 9]]
>>> b = copy.copy(a)              # 浅拷贝得到b
>>> c = copy.deepcopy(a)          # 深拷贝得到c
>>> print(id(a), id(b))           # a 和 b 不同
139832578518984 139832578335520
>>> for x, y in zip(a, b):        # a 和 b 的子对象相同
...     print(id(x), id(y))
...
139832578622816 139832578622816
139832578622672 139832578622672
139832578623104 139832578623104
>>> print(id(a), id(c))           # a 和 c 不同
139832578518984 139832578622456
>>> for x, y in zip(a, c):        # a 和 c 的子对象也不同
...     print(id(x), id(y))
...
139832578622816 139832578621520
139832578622672 139832578518912
139832578623104 139832578623392

从这个例子中可以清晰地看出浅拷贝与深拷贝地区别。

 总结:

1、赋值:简单地拷贝对象的引用,两个对象的id相同。

2、浅拷贝:创建一个新的组合对象,这个新对象与原对象共享内存中的子对象。

3、深拷贝:创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。

浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用。

python中赋值、浅拷贝、深拷贝详解(转)的更多相关文章

  1. python中赋值-浅拷贝-深拷贝之间的关系

    赋值: 变量的引用,没有拷贝空间 对象之间赋值本质上 是对象之间的引用传递而已.也就是多个对象指向同一个数据空间. 拷贝的对象分两种类型: . 拷贝可变类型 浅拷贝: 只拷贝第一层数据,不关心里面的第 ...

  2. Python中的高级数据结构详解

    这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...

  3. Python中格式化format()方法详解

    Python中格式化format()方法详解 Python中格式化输出字符串使用format()函数, 字符串即类, 可以使用方法; Python是完全面向对象的语言, 任何东西都是对象; 字符串的参 ...

  4. python中的tcp示例详解

    python中的tcp示例详解  目录 TCP简介 TCP介绍 TCP特点 TCP与UDP的不同点 udp通信模型 tcp客户端 tcp服务器 tcp注意点   TCP简介   TCP介绍 TCP协议 ...

  5. Python Deque 模块使用详解,python中yield的用法详解

    Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...

  6. Python中的魔术方法详解

    介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中 ...

  7. Python中的魔术方法详解(双下方法)

    介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中 ...

  8. python中的 zip函数详解

    python中zip()函数用法举例 定义:zip([iterable, ...]) zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple ...

  9. python中的buildin函数详解(第一篇)

    这会是很长的一个帖子,因为我打算从python最基础的东西开始,尝试去完全的掌握它,buildin中有一些常用的函数比如 abs, open, setattr, getattr, 大家都很了解他们的用 ...

  10. python中的yield生成器详解

    #原创,转载请先联系 在学习生成器之前,必须先了解一下迭代器.因为生成器就是一种特殊的迭代器,而且生成器用起来更加优雅. 迭代器的详解可以参考我的另一篇博文:https://www.cnblogs.c ...

随机推荐

  1. c#对一个类的扩展

    首先定义一个静态类,参数使用this约束并选择需要扩展的类,当然也可以 继续添加扩展是需要添加的参数 public static class StringExrprp { /// <summar ...

  2. UVA12545_Bits Equalizer

    题目意思很简单,给你两个串,第一个串为0,1或者?,第二个串为0,1, 每次你可以对第一个串进行三种操作,1.0变为1:2.?变为0或者1:3.交换任意两个数的位置. 现在问你能否把第一个串变为第一个 ...

  3. 51nod-1227-平均最小公倍数

    题意 定义 \(n\) 的平均最小公倍数: \[ A(n)=\frac{1}{n}\sum _{i=1}^n\text{lcm}(n,i) \] 求 \[ \sum _{i=L}^RA(i) \] \ ...

  4. 【开发工具IDE】解决IntelliJ IDEA 创建Maven项目速度慢的问题

    方法一(推荐) 在创建Maven项目时加上 archetypeCatalog=internal 参数,如下: 方法二 在maven的VM Options加上-DarchetypeCatalog=int ...

  5. P3386 【模板】二分图匹配

    题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...

  6. TechDay公开课实录:PaddlePaddle车牌识别实战和心得

    车牌识别作为一种常见的图像识别的应用场景,已经是一个非常成熟的业务了,在传统的车牌识别中,可以使用字符分割+字符识别的方式来进行车牌识别,而深度学习兴起后,出现了很多端到端的车牌识别模型,不用分割字符 ...

  7. 【JavaScript】事件

    一.前言         继续上一章的内容,继续今天的Js学习. 二.内容         事件处理程序 事件就是用户或浏览器自身执行的某种动作.而响应某个事件的函数就叫做事件处理程序 //HTML事 ...

  8. 大坑!有网,电脑qq登不上去!!

    手机qq --> 设置 --> 账号设备安全 -->  允许手机电脑同步在线 或是其他设置干扰导致

  9. redis2.4.conf配置文件中文释意

    # Redis示例配置文件 # 注意单位问题:当需要设置内存大小的时候,可以使用类似1k.5GB.4M这样的常见格式: # # 1k => 1000 bytes # 1kb => 1024 ...

  10. 用centos 6.5 webservice 安装系统后的问题

    编译pcre时:缺少一下库: yum -y install gcc yum -y install gcc-c++