针对Python的深浅拷贝问题

前些天做了个小程序,遇到了Python的深浅拷贝问题

感觉自己基础不够扎实,就翻了翻教程,真的是非常基础的知识。。。(各位大佬下手轻点2333)

下面简单说说:

首先有个字典a

1 a = {‘A‘:1,‘B‘:2,‘C‘:3,‘D‘:4}

然后我们把它赋值给另外一个空字典b

1 b = {}
2 b = a

当我们输出b时,可以看到a和b直观上看好像是相等了

按照常理,我们会认为a和b现在是两个值相等的字典,如果我们对其中一个操作,另外一个应该不会受到影响才对,所以我们试一下:

我们尝试删除b中的一个键值对

1 b.pop(‘A‘)

输出b

理所当然地b其中一个键值对被删除了

然后我们试着输出a,诡异的事情发生了

我们只是对b进行了键值对的删除,怎么a的值也变了?

原因就是Python的赋值原理

其实我们所谓的将a赋值给了b,赋给b的并不是a的值,而是a所存储的值的地址

所以当我们输出b的时候,输出的是和a一样的值

因此,我们对b进行的操作,都会影响到在内存中的{‘A‘:1,‘B‘:2,‘C‘:3,‘D‘:4}

当我们删除b的一个键值对时,其实就是对{‘A‘:1,‘B‘:2,‘C‘:3,‘D‘:4}的键值对进行了删除

此时a和b指向的就是新的字典{‘B‘: 2, ‘C‘: 3, ‘D‘: 4}

所以我们输出的时候发现值的变更

那么,如何真正的拷贝值呢?

这里就涉及到Python的深浅拷贝问题

使用Python的copy()和deepcopy()方法可以实现浅拷贝和深拷贝

什么是浅拷贝和深拷贝?

浅拷贝只对对象中的父对象进行拷贝,但不会连同其子对象一同复制

深拷贝则是对对象中的所有对象包括其子对象进行复制

举个例子:

(因为copy()方法和deepcopy()方法需要调用copy模块,故我们先提前引用)

import copy

定义字典a

1 a = {‘A‘:1,‘B‘:2,‘C‘:3,‘D‘:[1,2,3]}

作为对照组,我们创建b,同样将a赋给它(其实是传,你应该知道为什么了)

b = a

现在我们先进行浅拷贝

创建c,接收a的浅拷贝

1 c = copy.copy(a)

接下来进行深拷贝

1 d = copy.deepcopy(a)

之后,我们对a进行一系列改动,观察b,c,d的值的变化

首先我们对a的某键值对进行删除

1 a.pop(‘A‘)

然后我们对a中键为D的子对象进行改动,我们在D中添加一个子对象

a[‘D‘].append(4)

现在,我们分别输出a,b,c,d,观察他们的区别

首先是a,很显然的结果

其次是b,因为赋给引用的原因,同样会被改变,与a的值相同

再输出c,发现了端倪

再看看d

我们发现,a和b中的父对象及其子对象均受到了改变

c虽然父对象没有受到影响,但是其中键值为D的元素值(列表)发生了改变,所以由此我们发现,浅拷贝只会复制对象中的父对象,而其子对象在源数据收到改变时,仍会收到相同的影响

再转过来看d,与被我们改动前的a完全相同,所以说深拷贝非常完整地实现了对象的复制,由此我们发现,深拷贝可以复制对象的全部内容包括其子对象

为了更直观一点,可以参考下面的图:

所以,在进行数据拷贝时,可以视情况考虑拷贝的方式。当然这里还涉及到数据类型的可变和不可变类型的因素,这里不做过多讨论。

本文部分内容参考了Alex大佬的博客,对Python的深浅拷贝进行了非常详细的讨论,十分推荐大家去学习

传送门https://m.2cto.com/net/201606/515654.html

原文地址:https://www.cnblogs.com/seikito/p/9448142.html

时间: 2024-10-25 14:08:44

针对Python的深浅拷贝问题的相关文章

python之深浅拷贝(基础四)

第六章python之深浅拷贝(基础四) 6.1 小数据池 小数据池就是Python中一种提高效率的方式,固定数据类型使用同一个内存地址 小数池 -- 支持: str,int,bool a = 1 b = 1 id 查看空间的内存地址 获取开辟空间的一种地址 print(id(a)) print(id(b)) 小数据池数字支持范围: -5 ~ 256 *记住 a = 300 b = 300 print(id(a)) print(id(b)) 代码块: 一个文件,一个模块,一个函数,一个类,终端中每

Python的深浅拷贝

Python深浅拷贝 一丶引言 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 针对该列表 11 = ['a','b','c',['d','e','f']] 一般有三种方法,分别为:拷贝(赋值).浅拷贝.深拷贝 注意:拷贝/浅拷贝/深拷贝 都是针对数据可变类型数据而言的 1.1丶可变or不可变 id不变值可变,即在原值的基础上修改,则为可变数据类型:值变id也变,即重新申请一个空间放入新值,则

【python之路13】python的深浅拷贝

深浅拷贝 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import copy # ######### 数字.字符串 ######### n1 = 123 # n1 = "i am alex age 10" print(id(n1)) # ## 赋值 ## n2 = n1 print(id(n2)) # ## 浅拷贝 ## n2 = copy.copy(

python 赋值 深浅拷贝

深浅拷贝 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import copy # ######### 数字.字符串 ######### n1 = 123 # n1 = "i am alex age 10" print(id(n1)) # ## 赋值 ## n2 = n1 print(id(n2)) # ## 浅拷贝 ## n2 = copy.copy(

python笔记--深浅拷贝

深浅拷贝 1.对于数字.字符串和元组而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址,例如: >>> n1=123 >>> import copy >>> n2=n1    #赋值 >>> print(id(n2)) 31427456 >>> print n2 123 >>> n2=copy.copy(n1)    #浅拷贝 >>> print(id(n2)) 314

Python 的深浅拷贝 终于明白了

python 深浅拷贝不之前一直不太理解,只是概念性的理解像 1,2 所说,敲完下面代码希望你可以理解. 1.copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 >>> import copy >>> l1 = [1,3,5,['a','b','c']] >>> a = l1 >>> b = copy.copy(a) # 浅拷贝 >>>

我要学python之深浅拷贝原理

前言 在c++中参数传递有两种形式:值传递和引用传递.这两种方式的区别我不在此说,自行补上,如果你不知道的话.我先上python代码,看完我们总结一下,代码如下: # copy module import import copy # number and string a = 12 a1 = a a2 = copy.copy(a) a3 = copy.deepcopy(a) # look addr print("==========number=======") print(id(a)

Python入门-深浅拷贝

首先我们在这里先补充一下基础数据类型的一些知识: 一.循环删除 1.前面我们学了列表,字典和集合的一些操作方法:增删改查,现在我们来看一下这个问题: 有这样一个列表: lst = ['周杰伦','周润发','周星驰','刘德华'] 如果现在要求我们删除带'周'的元素,我们下意识会这样做: lst = ['周杰伦','周润发','周星驰','刘德华'] for i in lst: if '周' in i: lst.remove(i) print(lst) #['周润发', '刘德华'] 但是结果却

python(3)-深浅拷贝

import copy copy.copy()    浅拷贝 copy.deepcopy()   深拷贝 >>> import copy >>> a1 = 123 >>> a2 = a1 >>> a3 = copy.copy(a1) >>> a4 = copy.deepcopy(a1) >>> print(id(a1),id(a2),id(a3),id(a4)) 1967314832 1967314