Python 赋值、浅拷贝和深拷贝

初学Python,和C++还是有许多不同。直接赋值、浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别。Python语言的版本为2.7,在Pycharm中进行实验。

一、直接赋值

用下面的代码来实验:

 1 origin = [1, "string", [1, 3, 5]]
 2 Copy = origin
 3 print Copy
 4 print id(origin), id(Copy)
 5 Copy[0] = 5
 6 print origin, Copy
 7 Copy[1] = "changed"
 8 print origin, Copy
 9 Copy[2][0] = 111
10 print origin, Copy
11 print id(origin), id(Copy)

运行的结果如下:

[1, ‘string‘, [1, 3, 5]]
38994824 38994824
[5, ‘string‘, [1, 3, 5]] [5, ‘string‘, [1, 3, 5]]
[5, ‘changed‘, [1, 3, 5]] [5, ‘changed‘, [1, 3, 5]]
[5, ‘changed‘, [111, 3, 5]] [5, ‘changed‘, [111, 3, 5]]
38994824 38994824

可见,直接赋值的新变量完完全全就是一个原对象的引用,任何对复制对象的引用都会影响到原对象。

二、浅拷贝

用相同的代码来测试,仅仅把拷贝方式改成了copy.copy():

 1 import copy
 2 origin = [1, "string", [1, 3, 5]]
 3 Copy = copy.copy(origin)
 4 print Copy
 5 print id(origin), id(Copy)
 6 Copy[0] = 5
 7 print origin, Copy
 8 Copy[1] = "changed"
 9 print origin, Copy
10 Copy[2][0] = 111
11 print origin, Copy
12 print id(origin), id(Copy)

运行的结果如下:

[1, ‘string‘, [1, 3, 5]]
39453768 39510280
[1, ‘string‘, [1, 3, 5]] [5, ‘string‘, [1, 3, 5]]
[1, ‘string‘, [1, 3, 5]] [5, ‘changed‘, [1, 3, 5]]
[1, ‘string‘, [111, 3, 5]] [5, ‘changed‘, [111, 3, 5]]
39453768 39510280

这次可以发现,两个对象指向的内存并不相同,也就是说,浅拷贝的对象是一个新的对象。另外,可以发现,对新对象的元素进行替换并不会影响到原对象,而对子对象——列表的修改会影响到原对象。

三、深拷贝

同样,只是把拷贝方式换成copy.deepcopy():

 1 import copy
 2 origin = [1, "string", [1, 3, 5]]
 3 Copy = copy.deepcopy(origin)
 4 print Copy
 5 print id(origin), id(Copy)
 6 Copy[0] = 5
 7 print origin, Copy
 8 Copy[1] = "changed"
 9 print origin, Copy
10 Copy[2][0] = 111
11 print origin, Copy
12 print id(origin), id(Copy)

结果如下:

[1, ‘string‘, [1, 3, 5]]
39978056 39994504
[1, ‘string‘, [1, 3, 5]] [5, ‘string‘, [1, 3, 5]]
[1, ‘string‘, [1, 3, 5]] [5, ‘changed‘, [1, 3, 5]]
[1, ‘string‘, [1, 3, 5]] [5, ‘changed‘, [111, 3, 5]]
39978056 39994504

同样,两个对象指向的内存位置并不相同,说明创建了新对象。此外,新对象的任何改动都不影响到原有的对象。

结论:

(1)直接赋值是一个完完全全的引用,对新变量的任何改动都会影响到原对象。

(2)浅拷贝创建了新的对象,但是只拷贝了序列的元素,对于元素也是一个序列的情况(即子对象),只复制了对这个序列的引用!

(3)深拷贝是完完全全的拷贝,把原对象完整地拷贝到了新对象中。

原文地址:https://www.cnblogs.com/lustar/p/8372636.html

时间: 2024-08-29 22:08:25

Python 赋值、浅拷贝和深拷贝的相关文章

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

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

Python中的赋值,浅拷贝和深拷贝的区别

赋值 内存地址的引用,所有的改变都会同步 测试代码 #coding:utf-8 import copy a=['a','b',1,[1,2,3]] b = a #对象赋值,所有改动都会联动 a.append('d') a[0]='aaa' a[3].append(4) print a print b 运行结果 ['aaa', 'b', 1, [1, 2, 3, 4], 'd'] ['aaa', 'b', 1, [1, 2, 3, 4], 'd'] 浅拷贝 str,num等深浅拷贝都一样,list

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, 3

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列表--浅拷贝与深拷贝的区别

首先得说说列表为什么需要拷贝,就是为了解决简单赋值操作,传地址的问题,因为赋值过去的列表,其实指向的是同一个地址,问题说明看代码 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 列表浅拷贝与深拷贝

浅拷贝 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 学习]浅拷贝和深拷贝

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中关于赋值、浅拷贝与深拷贝的问题

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

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

在理解浅拷贝和深拷贝之前,首先要理解学习一下变量在Python中是怎样存储的: 变量的类型是分值引用与地址引用两种. python的一切变量都是对象,变量的存储,采用了地址引用的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量的只本身. 在Python中,是有多种数据类型:bool.int.long.float.string.list.dict.tuple.set; 其中可分为基本数据类型和复杂数据结构: 基本数据类型:bool.int.long.float.string; 复杂数据结