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

    Python深浅拷贝

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

    针对该列表l1=['a','b','c',['d','e','f']]一般有三种方法,分别为:拷贝(赋值)、浅拷贝、深拷贝

    注意:拷贝/浅拷贝/深拷贝都是针对可变类型数据而言的,id不变值可变,即在原值的基础上修改,则为可变数据类型;值变id也变,即重新申请一个空间放入新值,则为不可变数据类型。

    一、拷贝(赋值)

    如果l2是l1的拷贝对象,则l1内部的任何数据类型的元素变化,则l2内部的元素也会跟着改变,因为可变类型值变id不变。

    lt = [1, 2, 3, 4, 5]
    lt2 = lt
    lt.append(6)
    
    print(lt)
    
    # 因为列表是可变类型, 所以lt的值变化,lt2值也会跟着变化
    print(lt2)
    
    print(id(lt))
    print(id(lt2))
    

    结果:
    [1, 2, 3, 4, 5, 6]
    [1, 2, 3, 4, 5, 6]


    2304711549576
    2304711549576

    拷贝

    二、浅拷贝

    如果l2是l1的浅拷贝对象,则l1内的不可变元素发生了改变,l2不变;如果l1内的可变元素发生了改变,则l2会跟着改变。

    1. 添加值不发生变化

      import copy
      
      lt = [100, 200, 300, [400, 500, 600]]
      lt2 = copy.copy(lt)
      
      # 没有变化情况
      lt.append(700)
      print(lt)
      print(lt2)
      

      结果:

      [100, 200, 300, [400, 500, 600], 700]
      [100, 200, 300, [400, 500, 600]]

    2. 添加值发生变化

      import copy
      
      lt = [100, 200, 300, [400, 500, 600]]
      lt2 = copy.copy(lt)
      
      # 变化情况
      print('id(lt)',id(lt))
      print('id(lt[0])', id(lt[0]))
      print('id(lt[1])', id(lt[1]))
      print('id(lt[2])', id(lt[2]))
      print('id(lt[3])', id(lt[3]))
      print('*' * 50)
      print('id(lt2)',id(lt2))
      print('id(lt2[0])', id(lt2[0]))
      print('id(lt2[1])', id(lt2[1]))
      print('id(lt2[2])', id(lt2[2]))
      print('id(lt2[3])', id(lt2[3]))
      
      print('*' * 50)
      lt[-1].append(700)
      print(lt)
      print(lt2)
      

      结果:(浅拷贝,lt和lt2的id不一样,lt[-1]和lt[-1]一样)

      id(lt) 1520433324744
      id(lt[0]) 140712889544624
      id(lt[1]) 140712889547824
      id(lt[2]) 1520433550832
      id(lt[3]) 1520433324680


      id(lt2) 1520715912264
      id(lt2[0]) 140712889544624
      id(lt2[1]) 140712889547824
      id(lt2[2]) 1520433550832
      id(lt2[3]) 1520433324680


      [100, 200, 300, [400, 500, 600, 700]]
      [100, 200, 300, [400, 500, 600, 700]]

      浅拷贝

    三、深拷贝

    如果l2是l1的深拷贝对象,则l1内的不可变元素发生了改变,l2不变;如果l1内的可变元素发生了改变,l2也不会变,即l2永远不会因为l1的变化而变化。

    
    import copy
    
    lt = [100, 200, 300, [400, 500, 600]]
    lt2 = copy.deepcopy(lt)
    print('id(lt)',id(lt))
    print('id(lt[0])', id(lt[0]))
    print('id(lt[1])', id(lt[1]))
    print('id(lt[2])', id(lt[2]))
    print('id(lt[3])', id(lt[3]))
    print('*' * 50)
    
    print('id(lt2)',id(lt2))
    print('id(lt2[0])', id(lt2[0]))
    print('id(lt2[1])', id(lt2[1]))
    print('id(lt2[2])', id(lt2[2]))
    print('id(lt2[3])', id(lt2[3]))
    print('*' * 50)
    
    lt.append(70)
    print(lt)
    print(lt2)
    
    print("*" * 50)
    
    lt2[-1].append(7000)
    print(lt)
    print(lt2)
    
    

    结果:

    id(lt) 1585269859016
    id(lt[0]) 140712889544624
    id(lt[1]) 140712889547824
    id(lt[2]) 1585270085104
    id(lt[3]) 1585269858952


    id(lt2) 1585552380680
    id(lt2[0]) 140712889544624
    id(lt2[1]) 140712889547824
    id(lt2[2]) 1585270085104
    id(lt2[3]) 1585299572040


    [100, 200, 300, [400, 500, 600], 70]
    [100, 200, 300, [400, 500, 600]]


    [100, 200, 300, [400, 500, 600], 70]
    [100, 200, 300, [400, 500, 600, 7000]]

    深拷贝

    四、总结

    1. 拷贝:当lt2为lt的拷贝对象时, lt内可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化(简单赋值)
    2. 浅拷贝:当lt2为lt的拷贝对象时,lt内可变类型变化,lt2变化;lt内不可变类型变化,lt2不变化(copy.copy())
    3. 深拷贝:当lt2为lt的拷贝对象时, lt内的可变类型变化,lt2不变化;lt内不可变类型变化,lt2不变化(copy.deepcopy())

    注:拷贝/浅拷贝/深拷贝 只针对可变数据类型

    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:

    bzoj3052: [wc2013]糖果公园
    莫队算法心得
    bzoj1104: [POI2007]洪水pow
    bzoj1102: [POI2007]山峰和山谷Grz
    bzoj1121: [POI2008]激光发射器SZK
    bzoj1113: [Poi2008]海报PLA
    bzoj1103: [POI2007]大都市meg
    bzoj1396: 识别子串
    bzoj3756: Pty的字符串
  • 原文地址:https://www.cnblogs.com/randysun/p/11310170.html
Copyright © 2011-2022 走看看