python之浅拷贝与深拷贝

1. 浅拷贝

浅拷贝是对于一个对象的顶层拷贝
通俗的理解是:拷贝了引用,并没有拷贝内容

In [10]: a = [11,22,33]

In [11]: b = a

In [12]: id(a)
Out[12]: 140343572333832

In [13]: id(b)
Out[13]: 140343572333832

In [14]: a[0] = ‘aa‘

In [15]: a
Out[15]: [‘aa‘, 22, 33]

In [16]: b
Out[16]: [‘aa‘, 22, 33]

当b = a时,实际上是将a列表的内存地址赋值给了b,那么变量a与变量b指向的是同一内存地址!

2. 深拷贝

深拷贝是对于一个对象所有层次的拷贝(递归)

In [17]: import copy

In [18]: c = copy.deepcopy(a)

In [19]: id(a)
Out[19]: 140343572333832

In [20]: id(c)
Out[20]: 140343572336840

In [21]: a
Out[21]: [‘aa‘, 22, 33]

In [22]: c
Out[22]: [‘aa‘, 22, 33]

In [23]: a[0] = 11

In [24]: a
Out[24]: [11, 22, 33]

In [25]: c
Out[25]: [‘aa‘, 22, 33]

深拷贝不仅拷贝引用还拷贝值,所以内存地址不一样!

再看下面的代码,进一步理解浅拷贝与深拷贝:

注意:变量e由于用的是深拷贝,所以引用与值都是独立的一份

copy.copy

上面演示了copy.deepcopy的用法,下面看copy.copy的用法:

In [40]: a = [1,2,3]

In [41]: b = [4,5,6]

In [42]: c = [a,b]

In [43]: e = copy.copy(c)

In [44]: a.append(4)

In [45]: c[0]
Out[45]: [1, 2, 3, 4]

In [46]: id(c)
Out[46]: 140343572344200

In [47]: id(e)
Out[47]: 140343588052232

图解:

由于变量e用的是copy.copy(c)的方法,所以只拷贝了列表[a,b]的引用(copy.copy只能拷贝第一层引用),所以变量c与变量e的内存地址是不同的,但当改变[a,b]列表中a列表的值时,发现e变量中的a列表也会改变,说明copy.copy方法只拷贝了列表[a,b]列表的引用,而没有拷贝列表[a,b]中列表a与列表b的引用。实际上列表[a,b]中的两个列表a,b的内存地址还是指向的a与b

copy元组时的特点


copy.copy方法在copy时会自动判断copy的对象是可变类型还是不可变类型,如果是不可变类型,那么直接将引用指向copy的对象,如果是可变类型,那么只拷贝第一层的引用,后面的引用不会拷贝

原文地址:http://blog.51cto.com/12332406/2061426

时间: 2024-08-30 11:07:44

python之浅拷贝与深拷贝的相关文章

Python中浅拷贝和深拷贝的区别

Python中浅拷贝和深拷贝的区别 浅拷贝和深拷贝示意图 如上图,简单点说 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 数字,字符串是不可变类型 列表,字典是可变类型 我们看下面的案例 案例一:浅拷贝 >>> import copy     #导入copy模块                >>> s=['name',['savings',100.0]] #赋值给s >

python之浅拷贝和深拷贝

1.浅拷贝 1>赋值:从下面的例子我们可以看到赋值之后新变量的内存地址并没有发生任何变化,实际上python中的赋值操作不会开辟新的内存空间,它只是复制了新对象的引用,也就是说除了b这个名字以外,没有其他的内存开销,这时如果修改了a的值,就会影响b的值,同理,如果修改b的值,也会影响a的值. 2>浅拷贝是对引用的拷贝,它只拷贝了副对象,所以说id(a)!=id(c),那么对象内部的资源依然是引用,所以内部id(a[0])==id(c[0]).id(a[2][0])==id(c[2][0]),那

Python 列表浅拷贝与深拷贝

浅拷贝 shallow copy 和深拷贝 deep copy list.copy() 浅拷贝:复制此列表(只复制一层,不会复制深层对象) 等同于 L[:] 举例: 浅拷贝: a = [1.1, 2.2] # a = [1.1, 2.2] b = [1, 2, a] # b = [1, 2, [1.1, 2.2]] c = b.copy() # c = [1, 2, [1.1, 2,2]] a[0] = 1.123 b =  [1, 2, [1.123, 2.2]] c =  [1, 2, [1

python列表--浅拷贝与深拷贝的区别

首先得说说列表为什么需要拷贝,就是为了解决简单赋值操作,传地址的问题,因为赋值过去的列表,其实指向的是同一个地址,问题说明看代码 a = [1,2,3] b = a # list类型,简单赋值操作,是传地址 print(id(a)) print(id(b)) b[1] = 6 print(b) print(a) 执行结果,输出的是: 2460317409864 2460317409864 [1, 6, 3] [1, 6, 3] #同一地址,修改b的列表,a也会同时改变. 为了解决以上问题,lis

[python 学习]浅拷贝和深拷贝

import copy l=[1,3.14,[2,4,6]] l2=copy.copy(l) print(l) print(l2) print(id(l)) print(id(l2)) print('------------------------') for i in l: print(id(i)) print('------------------------') for i in l2: print(id(i)) #可见虽然l和l2的地址不一样,但里里面的内容都是一样的 #copy也就是浅

Python之美[从菜鸟到高手]--浅拷贝、深拷贝完全解读(copy源码分析)

可悲的我一直以为copy模块是用C写的,有时候需要深入了解deepcopy,文档描述的实在太简单,还是不知所云. 比如说最近看sqlmap源码中AttribDict的_deepcopy__有些疑惑, def __deepcopy__(self, memo): retVal = self.__class__() memo[id(self)] = retVal for attr in dir(self): if not attr.startswith('_'): value = getattr(se

python中关于赋值、浅拷贝与深拷贝的问题

Python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不同.如下: list_a = [1,2,3,"hello",["python","C++"]] list_b = list_a 这种情况下,list_b和list_a是一样的,他们指向同一片内存,list_b不过是list_a的别名,是引用. 我们可

一入python深似海--浅拷贝与深拷贝

python中有一个模块copy,deepcopy函数用于深拷贝,copy函数用于浅拷贝.要理解浅拷贝,必须先弄清楚python中的引用. 引用 Python中一切都是对象,变量中存放的是对象的引用.这是一个普遍的法则.可以说 Python 没有赋值,只有引用.如,a=1,变量a只是整数对象1的引用. 可变对象与不可变对象及其引用 一.不可变对象 不可变对象包括:数字,字符串,元组. 由于Python中的变量存放的是对象引用,所以对于不可变对象而言,尽管对象本身不可变,但变量的对象引用是可变的.

Python中赋值、浅拷贝与深拷贝

python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不同.如下: list_a = [1,2,3,"hello",["python","C++"]] list_b = list_a 这种情况下,list_b和list_a是一样的,他们指向同一片内存,list_b不过是list_a的别名,是引用. 我们可