• 深拷贝与浅拷贝


      在Python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,Python并没有拷贝这个对象,而只是拷贝了这个对象的引用。

    1、浅拷贝:利用切片操作、工厂方法list方法拷贝

    2、深拷贝:利用copy中的deepcopy方法进行拷贝

     

    一、浅拷贝

    如下,浅拷贝操作:

    In [113]: a=['chongyi',['zhang',22]]
    In [114]: b=a[:]

    b通过切片操作拷贝a

    In [115]: c=list(a)

    c通过工厂方法拷贝a

    In [116]: print id(a),id(b),id(c)
    50383040 49098264 50381384

    由上,从a、b、c的id值来看,三者是不同的对象

    1、操作1:更改a、b、c第一个元素

    In [126]: a[0]="jiangxi"
    In [127]: b[0]="shandong"
    In [128]: c[0]="shanghai"
    
    In [132]: print a,b,c
    ['jiangxi', ['zhang', 22]] ['shandong', ['zhang', 22]] ['shanghai', ['zhang', 22]]

    结果:各自更改成功,没有异常。

    2、操作2:更改b第二个元素里面的第二个元素

    In [137]: b[1][1]=18
    
    In [138]: print a,b,c
    ['jiangxi', ['zhang', 18]] ['shandong', ['zhang', 18]] ['shanghai', ['zhang', 18]]

    结果:只是想改b部分,却都发生了改变

    3、操作1、操作2解析

      针对第一个元素,a、b、c索引不同,更改一个后,其他的不会变,但是对于第二个元素列表['zhang', 22],a、b、c通过不同的索引指向了同一个索引,所以b改完后,其他a、c也都会变。

    二、深拷贝

      使用copy中的deepcopy方法进行拷贝。

    In [3]: a=['jiangxi',['chongyi',123]]
    
    In [4]: import copy
    
    In [5]: b=copy.deepcopy(a)
    In [6]: c=copy.deepcopy(a)
    
    In [7]: b[0]="shandong"
    In [8]: c[0]="shanghai"
    
    In [9]: print a,b,c
    ['jiangxi', ['chongyi', 123]] ['shandong', ['chongyi', 123]] ['shanghai', ['chongyi', 123]]
    
    In [10]: b[1][0]="jinan"
    
    In [11]: print a,b,c
    ['jiangxi', ['chongyi', 123]] ['shandong', ['jinan', 123]] ['shanghai', ['chongyi', 123]]

    由此可见:通过deepcopy的对象引用,互相不影响。

    In [12]: [id(x) for x in a]
    Out[12]: [46257376, 46218488]
    
    In [13]: [id(x) for x in b]
    Out[13]: [46257184, 46106600]
    
    In [14]: [id(x) for x in c]
    Out[14]: [46257472, 46248520]

      深拷贝就是在复制某些容器对象(list)的时候,重新在内存里分配一个空间存放复制过来的索引(引用---二层索引),不是重新复制一份底层的对象的内容在内存里。

      说白了,深拷贝,复制引用,且单独为其开辟一个内存空间存放。

    PS:

      1、容器:可以存放其他类型的内容

      2、列表(list):可以存放字符串、数值、列表

     

    三、深、浅拷贝总结

    思路一:利用切片操作和工厂方法list方法拷贝是浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。

    思路二:利用copy中的deepcopy方法进行拷贝是深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。

      对于数字,字符串和其他原子类型对象等,没有被拷贝的说法(没有层次),即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。

  • 相关阅读:
    Django-序列化器
    HTTP请求头响应头的信息
    HTTP协议
    IAAS,PAAS,SAAS
    MySQL-部分名词解释
    MySQL-事务和特性
    用Java仿QQ界面聊天小项目
    25篇Java入门技术博客,送给准备入坑的你
    Java自学推荐书籍
    Java中的并发讲解
  • 原文地址:https://www.cnblogs.com/geaozhang/p/7116025.html
Copyright © 2020-2023  润新知