zoukankan      html  css  js  c++  java
  • python 进阶篇 浅拷贝与深拷贝

    阐述引用、浅拷贝和深拷贝前,首先需要要了解 Python 的世界里,一切皆对象,每个对象各包含一个 idendity、type 和 value。

    iKXYpt

    引用(Reference)

    >>> b = [1 , 2]
    >>> a = [b, 3, 4]
    >>>
    >>> c = a
    >>> print c
    [[1, 2], 3, 4]
    >>> id(a)
    4408148552
    >>> id(c)
    4408148552
    

    c = a 表示 c 和 a 指向相同的地址空间,并没有创建新的对象。

    浅拷贝(Shallow copy)

    常见的浅拷贝的方法,是使用数据类型本身的构造器(list, tuple, dict, set),对于可变的序列(list, tuple),我们还可以通过切片操作符':'完成浅拷贝

    当然,Python 中也提供了相对应的函数 copy.copy(),适用于任何数据类型。

    xURgP9

    >>> import copy
    >>> d = copy.copy(a)
    >>> print d
    [[1, 2], 3, 4]
    >>>
    >>> id(a)
    4408148552
    >>> id(d)
    4408199792
    >>>
    >>> id(a[0])
    4408022944
    >>> id(d[0])
    4408022944
    >>>
    >>> d[0][0] = 5
    >>> print a
    >>> [[5, 2], 3, 4]
    

    d = copy.copy(a) 创建了一个新对象,复制了原有对象的引用。

    深拷贝(Deep copy)

    是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。

    Otkxv5

    >>> e = copy.deepcopy(a)
    >>> print e
    >>> [[1, 2], 3, 4]
    >>>
    >>> id(a)
    >>> 4408148552
    >>> id(e)
    >>> 4408394792
    >>>
    >>> id(a[0])
    >>> 4408022944
    >>> id(e[0])
    >>> 4408398432
    >>>
    >>> e[0][0] = 5
    >>> print a
    >>> [[1, 2], 3, 4]
    

    e = copy.deepcopy(a) 新建了一个新对象,完整的在内存中复制原有对象。

    Note

    关于浅拷贝和深拷贝的区别,Python 的 document 是这样解释的:

    The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

    • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
    • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

    使用深拷贝时,需要注意以下两个问题:

    • 递归对象拷贝: Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
    • 大对象拷贝: Because deep copy copies everything it may copy too much, e.g., administrative data structures that should be shared even between copies.

    思考题

    深度拷贝一个无限嵌套的列表。那么。当我们用等于操作符'=='进行比较时,输出会是什么呢?是 True 或者 False 还是其他?为什么呢?

    import copy
    x = [1]
    x.append(x)
    
    y = copy.deepcopy(x)
    
    # 以下命令的输出是?
    x == y
    

    程序会报错:RecursionError: maximum recursion depth exceeded in comparison。因为x是一个无限嵌套的列表,y深度拷贝x也是一个无限嵌套的列表,理论上x==y应该返回True,但是x==y内部执行是会递归遍历列表x和y中每一个元素的值,由于x和y是无限嵌套的,因此会stack overflow,报错

    参考

    大部分内容参考了博客,在基础上做了补充。

  • 相关阅读:
    使用Visual Studio 2010来部署Windows应用程序
    如何显示一个非激活窗体
    构建ASP.NET网站十大必备工具(2)
    在Azure中创建一个“Hello World”应用程序
    轻松搞定VS2010 和旧版本服务器一起使用的问题
    Sql注入与转义
    小数型 Float(M,D),decimal(M,D)
    MySQL SQL语句
    作业综合练习配置+自定义函数设置
    作业综合练习初始化工作
  • 原文地址:https://www.cnblogs.com/hiyang/p/12634664.html
Copyright © 2011-2022 走看看