zoukankan      html  css  js  c++  java
  • 深拷贝与浅拷贝

    前言

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

        

        为什么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
  • 相关阅读:
    基于alpine定制常用命令镜像
    sudo cat > EOF权限问题
    Nginx AWS ELB 域名解析后端502问题
    harbor使用aws s3存储
    Tomcat 优化和改进
    webservice 使用JaxWsDynamicClientFactory报空指针异常
    spring boot 集成 Apache CXF 调用 .NET 服务端 WebService
    eclipse launching workspace太慢的解决方法
    Remote System Explorer Operation卡死Eclipse解决方案
    同一个Tomcat 同一个端口 部署多个项目
  • 原文地址:https://www.cnblogs.com/117698ai/p/11449498.html
Copyright © 2011-2022 走看看