python中的深浅拷贝

Python中我们很多的时候会遇到数据拷贝的操作
Python中的数据拷贝分为深拷贝和浅拷贝

我们首先来说一下Python中的变量数据的存储和引用

In [1]: a = 1                                                                          

In [2]: b = 1                                                                          

In [3]: id(a)                                                                          
Out[3]: 4332267456

In [4]: id(b)                                                                          
Out[4]: 4332267456
#通过上边的代码我们可以发现,当我们给两个变量赋值相同的值是,它们的内存空间是相同的
#我们来说一下为什么
'''当我们给a赋值的时候,Python会在内存中开辟一块内存空间,
用来存储1这个值,并且开辟的内存空间有唯一的内存id进行标识,
然后a的变量就会指向1对应的内存空间的内存id
当我们调用a时,a首先通过内存id找到对应的内存空间,再从空间中将值取出
'''

以list列表为例说一下,序列的浅拷贝

In [1]: list1 = [1,2,3]                                                                

In [2]: list2 = list1                                                                  

In [3]: list3 = list1.copy()
  
In [6]: list4 = list1[:]  

In [7]: id(list1)                                                                      
Out[7]: 4460329928

In [8]: id(list2)                                                                      
Out[8]: 4460329928

In [9]: id(list3)                                                                      
Out[9]: 4461128584

In [10]: id(list4)                                                                     
Out[10]: 4460378248

'''
通过观察发现,第一种方式list1=list2使用的是同一个内存地址
而后两种方式都重新开辟了内存空间,虽然重新开辟了空间,但是它们的基础引用是没变的
'''
In [11]: id(list3[0])                                                                  
Out[11]: 4423530432

In [12]: id(list4[0])                                                                  
Out[12]: 4423530432

In [13]: id(list1[0])                                                                  
Out[13]: 4423530432
'''
当我们在对list3和list4进行重新赋值是,只是改变对它的内存指向,因为是新开辟的空间所以不会对list1产生影响
'''

我们再来说一下深层拷贝

#首先看一下,下面的例子
In [1]: list1 = [1,2,[3,4]]                                                            

In [2]: list2 = list1.copy()                                                           

In [3]: list1[2][0]                                                                    
Out[3]: 3

In [4]: list2[2][0]                                                                    
Out[4]: 3

In [5]: list1[2][0]=5                                                                  

In [6]: list2[2][0]                                                                    
Out[6]: 5

'''
观察上边的例子,我们尝试改变list中的内嵌的列表中的值发现,两个列表都发生了改变,这不是我们想要的结果
'''
#我们打印一下,内嵌列表的内存id看一下
In [7]: id(list1[2])                                                                   
Out[7]: 4423156104

In [8]: id(list2[2])                                                                   
Out[8]: 4423156104
#我们发现两个使用的是同一块内存空间,所以说我们改变一个值得时候另一个也发生了变化

#这个时候就需要使用,深层拷贝,当有内嵌的列表,元组,字典时我们需要开辟一个新的内存空间
In [9]: import copy                                                                    

In [10]: list3 = copy.deepcopy(list1)                                                  

In [11]: id(list1[2])                                                                  
Out[11]: 4423156104

In [12]: id(list3[2])                                                                  
Out[12]: 4440202312
#可以发现,我们成功的有开辟了一块内存空间,来存放与list1中内嵌列表相同的引用
#使用了不同的内存空间,当我们在改变内嵌列表的值得时候就不会受影响了
In [13]: list3[2][0] = 9                                                               

In [14]: list1[2][0]                                                                   
Out[14]: 5

In [15]: list3[2][0]                                                                   
Out[15]: 9

总结一下
浅层拷贝:是重新开辟一块内存空间,来存放元素的引用,但是当存在内嵌的序列时也只是对序列的引用
深层拷贝:重新开辟内存空间,来存放元素的引用,当发现有内嵌的序列时也重新开辟内存空间,来存放对内嵌元素的引用

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读