python 进阶篇 浅拷贝与深拷贝
阐述引用、浅拷贝和深拷贝前,首先需要要了解 Python 的世界里,一切皆对象,每个对象各包含一个 idendity、type 和 value。

引用(Reference)

>>> b = [1 , 2]
>>> a = [b, 3, 4]
>>>
>>> c = a
>>> print c
[[1, 2], 3, 4]
>>> id(a)
4408148552
>>> id(c)
4408148552
c = a 表示 c 和 a 指向相同的地址空间,并没有创建新的对象。
浅拷贝(Shallow copy)
常见的浅拷贝的方法,是使用数据类型本身的构造器(list, tuple, dict, set),对于可变的序列(list, tuple),我们还可以通过切片操作符':'完成浅拷贝
当然,Python 中也提供了相对应的函数 copy.copy(),适用于任何数据类型。

>>> import copy
>>> d = copy.copy(a)
>>> print d
[[1, 2], 3, 4]
>>>
>>> id(a)
4408148552
>>> id(d)
4408199792
>>>
>>> id(a[0])
4408022944
>>> id(d[0])
4408022944
>>>
>>> d[0][0] = 5
>>> print a
>>> [[5, 2], 3, 4]
d = copy.copy(a) 创建了一个新对象,复制了原有对象的引用。
深拷贝(Deep copy)
是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。

>>> e = copy.deepcopy(a)
>>> print e
>>> [[1, 2], 3, 4]
>>>
>>> id(a)
>>> 4408148552
>>> id(e)
>>> 4408394792
>>>
>>> id(a[0])
>>> 4408022944
>>> id(e[0])
>>> 4408398432
>>>
>>> e[0][0] = 5
>>> print a
>>> [[1, 2], 3, 4]
e = copy.deepcopy(a) 新建了一个新对象,完整的在内存中复制原有对象。
Note
关于浅拷贝和深拷贝的区别,Python 的 document 是这样解释的:
The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):
- A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
- A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
使用深拷贝时,需要注意以下两个问题:
- 递归对象拷贝: Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
- 大对象拷贝: Because deep copy copies everything it may copy too much, e.g., administrative data structures that should be shared even between copies.
思考题
深度拷贝一个无限嵌套的列表。那么。当我们用等于操作符'=='进行比较时,输出会是什么呢?是 True 或者 False 还是其他?为什么呢?
import copy
x = [1]
x.append(x)
y = copy.deepcopy(x)
# 以下命令的输出是?
x == y
程序会报错:RecursionError: maximum recursion depth exceeded in comparison。因为x是一个无限嵌套的列表,y深度拷贝x也是一个无限嵌套的列表,理论上x==y应该返回True,但是x==y内部执行是会递归遍历列表x和y中每一个元素的值,由于x和y是无限嵌套的,因此会stack overflow,报错
参考
大部分内容参考了博客,在基础上做了补充。
python 进阶篇 浅拷贝与深拷贝的更多相关文章
- python进阶篇
python进阶篇 import 导入模块 sys.path:获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到. import sys ...
- Python 引用、浅拷贝、深拷贝解析
引用 Python是动态数据类型的语言,故在对变量进行赋值时是不用制定变量类型的. 或者说,你可以把变量赋值的过程,当作是贴一个标签,去引用该数据. 看下面的例子: In [54]: a=4 In [ ...
- python赋值、浅拷贝、深拷贝区别
在写Python过程中,经常会遇到对象的拷贝,如果不理解浅拷贝和深拷贝的概念,你的代码就可能出现一些问题.所以,在这里按个人的理解谈谈它们之间的区别. 一.赋值(assignment) 在<Py ...
- Python 赋值、浅拷贝和深拷贝
初学Python,和C++还是有许多不同.直接赋值.浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别.Python语言的版本为2.7,在Pycharm中进行实验. 一.直接赋值 用下面的代码来 ...
- Python赋值、浅拷贝、深拷贝
一.赋值(assignment) >>> a = [1, 2, 3] >>> b = a >>> print(id(a), id(b), sep= ...
- javascript篇-浅拷贝与深拷贝
理解javascript 的浅拷贝与深拷贝,首先看一下js的数据类型: js有5种基本数据类型:undefined,null,boolean,number,string 还有一种复杂的数据类型(也叫引 ...
- python 基础之浅拷贝与深拷贝
浅拷贝与深拷贝 1.普通赋值 例1: a = 15b = aa = 16print(b)#例2:lst1 = [1,2,3]lst2 = lst1lst1.append(4)print(lst2)#这 ...
- python中的浅拷贝,深拷贝
直接引用,间接引用 # 1.列表存储的是索引对应值的内存地址,值会单独的开辟一个内存空间 list = ["a","b"] 内存里面存储的就是list[0],l ...
- python进阶(6)深拷贝和浅拷贝
深拷贝和浅拷贝 不管对于浅拷贝.还是深拷贝,针对不可变对象str.int.tuple(有点特殊).boolean,它的内存地址是不变的,拷贝的仅仅是值 import copy a = 1 b = co ...
随机推荐
- w3cshool -- 排列组合去重算法挑战
function permAlone(str) { if(str.length == 1) return str; var a = str.substr(0, 1), one = [a], count ...
- Linux下的ngnix安装与启动
Linux安装Nginx 1.安装gcc gcc-c++(如新环境,未安装请先安装)$ yum install -y gcc gcc-c++2.安装wget$ yum -y install wget ...
- CUDA编程入门
CUDA是一个并行计算框架.用于计算加速.是nvidia家的产品.广泛地应用于现在的深度学习加速. 一句话描述就是:cuda帮助我们把运算从cpu放到gpu上做,gpu多线程同时处理运算,达到加速效果 ...
- 简单实现Win10炫酷下滑关机
实现效果如下图,鼠标左键按下下拉关机: 先说下实现思路和实现过程(包括失败过程),不想了解的可直接往下拉查看红色字体标注的最终实现方法. 首先实现下滑关机的Windows自带的一个功能(程序)Slid ...
- .gitattributes
.gitattributes文件是一个文本文件,文件中的一行定义一个路径的若干属性.以行为单位设置一个路径下所有文件的属性,格式如下: 要匹配的文件模式 属性1 属性2 GRLF和LF CRLF,LF ...
- awk扩展应用
awk扩展应用 案例1:使用awk提取文本 案例2:aw ...
- JDK+maven安装
JDK+Maven安装汇总: 1.JDK1.8: 链接:https://pan.baidu.com/s/1d04iZagXqzG-DoGV5oUFug 提取码:bd1m Maven3.6.3: 链接: ...
- python--一些知识点
一. ==和is的区别 1. ==意为左右两端的值是否相等 2. is意为,左边是否就是右边,python会检测左右两边的引用位置,相等才是True(注:一定范围内的数字,左右两边为True) 二. ...
- node.js代码二
var express = require('express'); var app = express(); var server = require('http').Server(app); var ...
- 如何将icon图标库引入自己的项目中
---恢复内容开始--- 今天是18年的国庆,趁着国庆的这股开心劲儿,开开心心的写点东西: 第一篇:关于如何将icon图标库引入自己的项目(此方法Taro,微信小程序,支付宝小程序等均适用,不会存在不 ...