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

    定义:

    • =号浅拷贝:在Python中对象的赋值其实就是对象的引用。copy了之后两个仍然是同一个东西。那么他们内部的元素自然也是一样的,对其中一个进行修改,另一个也会跟着变>
    • copy()浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制.(copy了子对象)
    • copy.deepcopy()深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。(子对象的子对象都copy了,很强大)

    几个术语的解释:

    1. 变量:是一个系统表的元素,拥有指向对象的连接空间 
    2. 对象:被分配的一块内存,存储其所代表的值 
    3. 引用:是自动形成的从变量到对象的指针 
    4. 注意:类型(int类型,long类型(python3已去除long类型,只剩下int类型的数据))属于对象,不是变量 
    5. 不可变对象:一旦创建就不可修改的对象,包括字符串、元组、数字 
    6. 可变对象:可以修改的对象,包括列表、字典。

    应用的范围:

    1. 切片可以应用于:列表、元组、字符串,但不能应用于字典。 
    2. 深浅拷贝,既可应用序列(列表、元组、字符串),也可应用字典。

    深浅拷贝的作用:

    1. 减少内存的使用。
    2. 以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。

    对于不可变对象的深浅拷贝:

    • 不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。
    • 一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。
    #先来简单的小示例
    L = [1,2,3,[4,5,6],7]
    
    #=号copy
    a = L
    
    #浅copy
    b = L.copy()
    
    #深copy
    import copy
    c = copy.deepcopy(L)
    
    print(L)
    print(a)
    print(b)
    print(c)
    
    L.remove(1)
    L[3].remove(4)
    
    print(L)
    print(a)
    print(b)
    print(c)
    
    #输出结果
    [1, 2, 3, [4, 5, 6], 7]
    [1, 2, 3, [4, 5, 6], 7]
    [1, 2, 3, [4, 5, 6], 7]
    [1, 2, 3, [4, 5, 6], 7]
    
    [1, 2, 3, [5, 6]]              # L
    [1, 2, 3, [5, 6]]              # =号:指向型copy,都一样
    [1, 2, 3, [5, 6], 7]           # 浅copy,只copy到子对象
    [1, 2, 3, [4, 5, 6], 7]        # 深copy,子对象的子对象都copy,非常暴力

    copy的内存地址详解:

    import copy

    a=(1,2,3) print("=====第一种=号浅拷贝=====") b=a print(a) print(b) print(id(a)) print(id(b)) print("=====另一种copy浅拷贝===") b=copy.copy(a) print(a) print(b) print(id(a)) print(id(b)) print("=====深拷贝=====") b=copy.deepcopy(a) print(a) print(b) print(id(a)) print(id(b)) # 结果如下: =====浅拷贝===== (1, 2, 3) (1, 2, 3) 2814522335952 2814522335952 =====另一种浅拷贝=== (1, 2, 3) (1, 2, 3) 2814522335952 2814522335952 =====深拷贝===== (1, 2, 3) (1, 2, 3) 2814522335952 2814522335952

    对于可变对象深浅拷贝:

    • =浅拷贝:值相等,地址相等 
    • copy浅拷贝:值相等,地址不相等 
    • deepcopy深拷贝:值相等,地址不相等
    import copy

    a=[1,2,3] print("=====第一种=号浅拷贝=====") b=a print(a) print(b) print(id(a)) print(id(b)) print("=====另一种copy浅拷贝===") b=copy.copy(a) print(a) print(b) print(id(a)) print(id(b)) print("=====深拷贝=====") b=copy.deepcopy(a) print(a) print(b) print(id(a)) print(id(b)) #结果如下: =====浅拷贝===== [1, 2, 3] [1, 2, 3] 2007696321544 2007696321544 =====另一种copy浅拷贝=== [1, 2, 3] [1, 2, 3] 2007696321544 2007695909960 =====深拷贝===== [1, 2, 3] [1, 2, 3] 2007696321544 2007696319560
    '''注意'''
    m = [1, 2, [3]]
    n = m       # =号浅拷贝
    n[1] = 4
    n[2][0] = 5
    print(m)
    #输出[1, 4, [5]]
    
    m = [1, 2, [3]]
    n = m[:]   # 效果等同copy浅拷贝
    n[1] = 4
    n[2][0] = 5
    print(m)
    #输出 [1, 2, [5]]

    总结:

    1,深浅拷贝都是对源对象的复制,占用不同的内存空间。

    2,不可变类型的对象,对于深浅拷贝毫无影响,最终的地址值和值都是相等的。

    3,可变类型: 
    =浅拷贝: 值相等,地址相等 
    copy浅拷贝:值相等,地址不相等 
    deepcopy深拷贝:值相等,地址不相等

     

     学习内容参考:

    Python中深拷贝与浅拷贝的区别

    大家都是拷贝,凭什么你这么秀?

  • 相关阅读:
    mvc edmx 的config文件
    Openwrt安装软件的方法
    如何用JQuery实现单元格 循环变背景色
    Vue的生命周期
    hmtl弹出框样式
    在星巴克买咖啡思考技术团队的管理
    RealTimePerformanceDemoView
    《SAAS创业指南》拆书笔记——产品打磨和商业模式初步验证
    基于日志的回放对比系统设计
    异常测试-中间件故障演练
  • 原文地址:https://www.cnblogs.com/kumata/p/9099345.html
Copyright © 2011-2022 走看看