欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

深拷贝与浅拷贝

程序员文章站 2022-06-22 10:50:51
前言 在说深浅拷贝之前,我们要明白以下原因是怎么产生的: 为什么a的数值就会变呢,我只是在b中添加了一个数值15,怎么a中也会添加一个15呢?原来python中所采用的的引用的方法,就是说a变量只是指向[13,14]这一个地址,当b = a时,并没有重新开辟一个新的地址,而是将b指向[13,14]这 ......

前言

    在说深浅拷贝之前,我们要明白以下原因是怎么产生的:

    深拷贝与浅拷贝

 

 

    为什么a的数值就会变呢,我只是在b中添加了一个数值15,怎么a中也会添加一个15呢?原来python中所采用的的引用的方法,就是说a变量只是指向[13,14]这一个地址,当b = a时,并没有重新开辟一个新的地址,而是将b指向[13,14]这个地址,所以当执行b.append(15)时,就是在原地址的基础改的,即牵一发而动全身。下图可以更加清晰的表达出来。

 

  深拷贝与浅拷贝

 

 

深拷贝

 

  何为深拷贝,重新在复制一份,新的这一份数值与旧的这一份一样,但是地址已经不一样了,他们已经没有的任何关系了,如下代码所示:

 

  

in [4]: a = [11,12]  #将[11,12]赋值给a

in [5]: b = a   #将a赋值给b

in [6]: id(a)   #获取a的地址
out[6]:     2321940139848

in [7]: id(b)  #获取b的地址,并且与a的地址相同
out[7]: 2321940139848

in [8]: import copy  #深拷贝需要通过copy这个模块来实现

in [9]: c = copy.deepcopy(a)  #将a深拷贝给c

in [10]: id(a)      #获取a的地址
out[10]: 2321940139848

in [11]: id(c)      #获取b的地址,发现与a的截然不同,已完成了深拷贝
out[11]: 2321937374344

in [12]: a  #打印出a的值
out[12]: [11, 12]

in [13]: c  #打印出b的值
out[13]: [11, 12]

in [14]: a.append(33) #在a中新添加一个33的新值

in [15]: a  #打印出a的值,发现其值已经改变
out[15]: [11, 12, 33]

in [16]: c  #打印出c的值,发现其值没有改变,说明这是深拷贝
out[16]: [11, 12]

in [17]:

 

in [32]: a = [11,22]

in [33]: b = [33,44]

in [34]: c = [a,b]

in [35]: d = copy.deepcopy(c)

in [36]: id(c)
out[36]: 2321946266696

in [37]: id(d)
out[37]: 2321943989128

in [38]: id(c[0])
out[38]: 2321948894472

in [39]: id(d[0])
out[39]: 2321946155976

in [40]: a.append(55)

in [41]: c
out[41]: [[11, 22, 55], [33, 44]]

in [42]: d
out[42]: [[11, 22], [33, 44]]

 

浅拷贝

  即只拷贝第一层,深入就不拷贝,此之谓浅拷贝,如下类代码说话

  

in [18]: #当一个变量=xxxx的时候,可以理解为这个变量指向的xxxx

in [20]: # 完成浅拷贝copy.copy

in [21]: # 完成深拷贝copy.deepcopy

in [22]: a = [11,22]  #给a赋值
 
in [23]: b = [33,44]    #给b赋值

in [24]: c = [a,b]       #给c赋值

in [25]: d = c        #d指向c的指向

in [26]: e = copy.copy(c)  #拷贝c给d

in [27]: id(c)         #打印出c的地址
out[27]: 2321944795080

in [28]: id(e)       #打印e的地址,与c不同,说明完成了第一层的拷贝
out[28]: 2321938538568

in [29]: id(e[1])   #打印出e的第二层地址
out[29]: 2321938541448

in [30]: id(c[1])   #打印出c的第二层地址,与e 的第二层地址相同,说明没有拷贝成功
out[30]: 2321938541448

in [31]:

            

注意注意 

 当copy.copy进行浅拷贝和copy.deepcopy进行深拷贝的时候,遇到第一层为不可变数据类型并且里面都不可变类型,则无法进行拷贝,两个还是同时指向同一个。但是第一层为不可变类型,第二层为可变类型,copy.copy不进行拷贝,copy.deepcopy进行拷贝

  

in [44]: a = [11,22]

in [45]: b = a

in [46]: id(a)
out[46]: 2321947428616

in [47]: id(b)
out[47]: 2321947428616

in [48]: c = copy.copy(a)

in [49]: id(c)
out[49]: 2321934839368

in [50]: a = (11,22)

in [51]: b = copy.copy(a)

in [52]: id(a)
out[52]: 2321938558344

in [53]: id(b)
out[53]: 2321938558344