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

    定义:所谓浅拷贝就是对引用的拷贝;所谓深拷贝就是对对象的资源的拷贝。

    1、对于直接赋值(=),有如下三点认识:

      1)、赋值是将一个对象的地址赋值给一个变量,让变量指向该地址(旧瓶装旧酒)。
      2)、修改不可变对象(str、tuple)需要开辟新的空间
      3)、修改可变对象(list等)不需要开辟新的空间

    • 浅拷贝仅仅复制了容器中元素的地址
    #对于赋值运算,就是指向同一个内存地址.
    s1 = 'alex'
    s2 = s1
    print(s1, id(s1))    #alex 1996081840344
    print(s2, id(s2))    #alex 1996081840344
    #当s1的值修改时,内存地址也发生了变化
    s1 = 'alex'
    print(s1, id(s1))    #alex 1515050615000
    s1 = 'alex2'
    print(s1, id(s1))    #alex 1515051454624
    #当列表l1新增一个值,其内存地址不变
    l1 = [1,2,3]
    l2 = l1
    print(l1, id(l1))   #[1, 2, 3]    1730542337864
    print(l2, id(l2))   #[1, 2, 3]    1730542337864
    l1.append(4)
    print(l1, id(l1))   #[1, 2, 3, 4] 1730542337864
    print(l2, id(l2))   #[1, 2, 3, 4] 1730542337864

    2、copy浅拷贝,只拷贝父对象,没拷贝子对象,所以原始数据改变,子对象会改变

    #切片赋值相当于浅copy,只拷贝值,不拷贝内存地址
    l1 = [1,2,3]
    l2 = l1[:]
    print(l1, id(l1))   #[1, 2, 3] 2685913624392
    print(l2, id(l2))   #[1, 2, 3] 2685913645192
    l1.append(4)
    print(l1, id(l1))   #[1, 2, 3, 4] 2685913624392
    print(l2, id(l2))   #[1, 2, 3]    2685913645192
    #只拷贝父对象第一次的值,不拷贝内存地址
    l1 = [1,2,3]
    l2 = l1.copy()
    l1.append(666)
    print(l1, id(l1))     #[1, 2, 3, 666] 2170284179272
    print(l2, id(l2))     #[1, 2, 3]      2170284195976
    #对于浅copy来说,第一层都是独立的内存地址,从第二层开始,都是指向同一个内存地址,一变都变
    l1 = [1,2,3,[22,33]]
    l2 = l1.copy()
    l1[3].append(666)
    print(l1, id(l1))     #[1, 2, 3, [22, 33, 666]] 1643848253576
    print(l2, id(l2))     #[1, 2, 3, [22, 33, 666]] 1643848253704
    

    3、deepcopy深拷贝,包含父对象及其子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变 

    #对于深copy来说,无论多少层,在内存中都是两个独立的内存地址
    import copy     #引入copy模块
    
    l1 = [1,[22,33]]
    l2 = copy.deepcopy(l1)
    l1.append(77)
    l1[1].append(66)
    print(l1, id(l1), id(l1[1]))    #[1, [22, 33, 66], 77] 1756548727112 1756548726920
    print(l2, id(l2), id(l2[1]))    #[1, [22, 33]]         1756548728392 1756548728328
    

    总结:  

      1、深浅拷贝都是对源对象的复制,占用不同的内存空间。
      2、不可变类型(数字、字符串、元组)的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。
      3、可变类型(列表、字典):
        =浅拷贝: 值相等,地址相等
        copy浅拷贝:值相等,地址不相等
        deepcopy深拷贝:值相等,地址不相等

  • 相关阅读:
    Windows Service 2016 DatacenterStandEmbedded激活方法
    批处理文件设置IP以及DNS
    C#类的一些基础知识(静态方法可以不用实例化调用)
    Dynamics Crm Plugin插件注册的问题及解决方案(持续更新。。。。。。)
    【转载】C# get 与set的一些说明
    C#补位函数PadLeft和PadRight
    Kubernetes集群调度之Scheduler
    Kubernetes集群控制之ControllerManager
    Kubernetes集群大脑之apiserver
    Kubernetes集群存储之etcd
  • 原文地址:https://www.cnblogs.com/lioushell/p/8378380.html
Copyright © 2011-2022 走看看