Python 对象的深拷贝与浅拷贝 -- (转)
本文内容是在《Python核心编程2》上看到的,感觉很有用便写出来,给大家参考参考!
浅拷贝
首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法。然后使用id函数来看看它们的标示符
1
2
3
4
5
6
7
|
# encoding=UTF-8 obj = [ 'name' ,[ 'age' ,18]] a=obj[:] b=list(obj) for x in obj,a,b: print id (x) |
他们的id都不同,按照正常的判断,三个不同id的对象应该都是独立的。那么我们先给他们改改名看看
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# encoding=UTF-8 obj = [ 'name' ,[ 'age' , 18 ]] a = obj[:] b = list (obj) for x in obj,a,b: print id (x) a[ 0 ] = 'lisi' b[ 0 ] = 'zhangsan' print a print b |
对象a与b分别赋予了不同的名字,下来我们来看看给a对象改一个年龄
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# encoding=UTF-8 obj = [ 'name' ,[ 'age' , 18 ]] a = obj[:] b = list (obj) for x in obj,a,b: print id (x) a[ 0 ] = 'lisi' b[ 0 ] = 'zhangsan' print a print b a[ 1 ][ 1 ] = 25 print a print b |
细心的朋友应该看出来了,改变a[0]元素与b[0]元素都互不影响,为何改变a[1][1]的元素会影响b[1][1]的元素呢?
要解开这个问题,只有先了解深拷贝与浅拷贝。以上实例中,我们创建的a与b都是从obj对象的浅拷贝,obj中第一个元素是字符串属于不可变类型,第二个元素是列表属于可变类型。因此我们进行拷贝对象时,字符串被显示拷贝重新创建了一个字符串,而列表只是复制引用,所以改变列表的元素会影响所有引用对象。从下列的id值中,你就能看明白了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# encoding=UTF-8 obj = [ 'name' ,[ 'age' , 18 ]] a = obj[:] b = list (obj) for x in obj,a,b: print id (x[ 0 ]), id (x[ 1 ]) print a[ 0 ] = 'lisi' b[ 0 ] = 'zhangsan' for x in obj,a,b: print id (x[ 0 ]), id (x[ 1 ]) print a[ 1 ][ 1 ] = 25 b[ 1 ][ 1 ] = 30 for x in obj,a,b: print id (x[ 0 ]), id (x[ 1 ]) print |
复制对象的时候,我们可以看到所有元素的id都一直,我们分别改变了a与b对象的第一个字符串元素,因为字符串是不可变对象,所以改变后等于新创建,于是a与b的第一个字符串元素id不一致。而a与b的第二个元素都是列表可变对象,所以无论修改任何一个id值都表示一个指针,始终影响其它引用对象的值。
因此也就为什么修改a对象的年龄会影响b对象的年龄值,或者修改b对象的年龄值也会影响a对象的年龄值,包括obj对象在内。
深拷贝
以上都是浅拷贝,那么我们希望拷贝的对象是独立的,修改时不要影响其它值,这种我们称为深拷贝。实现深拷贝我们需要引用一个copy模块,copy模块有两个函数可用,一个是copy浅拷贝;另一个是deepcopy深拷贝。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# encoding=UTF-8 import copy obj = [ 'name' ,[ 'age' , 18 ]] a = copy.deepcopy(obj) b = copy.deepcopy(obj) for x in a,b: print id (x[ 0 ]), id (x[ 1 ]) print a[ 1 ][ 1 ] = 25 b[ 1 ][ 1 ] = 30 print a print b |
使用深拷贝后,列表元素的id不一致,表示独立对象,修改任何一个列表元素的值都不会影响其它对象。
以下是几点拷贝操作的注意事项:
第一、非容器类型(比如数字、字符串和其它“院子”类型的对象,像代码、类型和range对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成。
第二、如果元祖变量只包含原子类型对象,对它的深拷贝将不会进行。
我们把上面的例子改成元祖,然后使用深拷贝试试
1
2
3
4
5
6
7
8
9
|
# encoding=UTF-8 import copy obj = [ 'name' ,( 'age' , 18 )] a = copy.deepcopy(obj) b = copy.deepcopy(obj) for x in a,b: print id (x), id (x[ 1 ]) print |
文章来源:http://www.qttc.net/201302282.html
Python 对象的深拷贝与浅拷贝 -- (转)的更多相关文章
- Python对象拷贝——深拷贝与浅拷贝
对象赋值 浅拷贝 深拷贝 1. 对象赋值 对象的赋值实际上是对对象的引用.也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用.如: >>> t1 = tuple('furzoom ...
- **Python中的深拷贝和浅拷贝详解
Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要 ...
- Python赋值语句与深拷贝、浅拷贝的区别
参考:http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-d ...
- java 复制Map对象(深拷贝与浅拷贝)
java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...
- 谈谈java中对象的深拷贝与浅拷贝
知识点:java中关于Object.clone方法,对象的深拷贝与浅拷贝 引言: 在一些场景中,我们需要获取到一个对象的拷贝,这时候就可以用java中的Object.clone方法进行对象的复制,得到 ...
- python中的深拷贝与浅拷贝
深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...
- 浅谈python 复制(深拷贝,浅拷贝)
博客参考:点击这里 python中对象的复制以及浅拷贝,深拷贝是存在差异的,这儿我们主要以可变变量来演示,不可变变量则不存在赋值/拷贝上的问题(下文会有解释),具体差异如下文所示 1.赋值: a=[1 ...
- python中的深拷贝和浅拷贝
python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...
- 001 说说Python中的深拷贝和浅拷贝
在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...
随机推荐
- python爬虫 --- 简书评论
某些网站的一些数据是通过js加载的 ,所以爬取下来的数据拿不到, 找到评论的地址 .进行请求获取评论数据 #coding=utf-8 import json import requests def r ...
- django 使用json.dumps转换queryset的datatime报错问题解决
最近在使用django做项目的时候想使用ajax来实现前后台数据的交互,但是在将数据库查询结果转换成json数据时,遇到时间格式的数据转换遇到问题,无法正确的进行转换,具体如下: 转换成json时使用 ...
- ViewData与ViewBag
ViewData与ViewBag使用的是同一个数据源,因此数据一样,只是ViewBag 不再是字典的键值对结构,而是 dynamic 动态类型(http://www.cnblogs.com/kissd ...
- MATLAB中imfilter函数
功能:对任意类型数组或多维图像进行滤波. 用法:B = imfilter(A,H) B = imfilter(A,H,option1,option2,...) 或写作g = imfilter(f, w ...
- java 中 Stringbuff append源代码浅析
public synchronized StringBuffer append(String str) { super.append(str); return this; ...
- 【hdu4734】F(x) 数位dp
题目描述 对于一个非负整数 $x=\overline{a_na_{n-1}...a_2a_1}$ ,设 $F(x)=a_n·2^{n-1}+a_{n-1}·2^{n-2}+...+a_2·2^1+ ...
- ADC关键性能指标及误区
ADC关键性能指标及误区 由于ADC产品相对于网络产品和服务器需求小很多,用户和集成商在选择产品时对关键指标的理解难免有一些误区,加之部分主流厂商刻意引导,招标规范往往有不少非关键指标作被作为必须符合 ...
- 【题解】CF#403 D-Beautiful Pairs of Numbers
这题还挺对胃口的哈哈~是喜欢的画风!回家路上一边听歌一边想到的解法,写出来记录一下…… 首先,由于 \(b_{k} < a_{k + 1}\) ,所以我们可以看作是在一个长度为 n 的序列上选择 ...
- lalala
<script type="text/javascript"> var a_idx = 0; var b_idx = 0; var a = new Array(&quo ...
- BZOJ3195:[JXOI2012]奇怪的道路——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=3195 Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方 ...