美文网首页Python应用集
Python深拷贝、浅拷贝

Python深拷贝、浅拷贝

作者: Solomon_Xie | 来源:发表于2019-01-17 03:33 被阅读1次

    Python中有三种拷贝:

    • =:完全不拷贝,指针指向同一块内存数据
    • copy.copy():浅拷贝,为新变量开创内存空间,但是如果变量里面有子变量,则子变量只是指向原先对应的内存空间。
    • copy.deepcopy():深拷贝,为新变量重新开创内存空间,变量里面如果有子变量也全都重新开内存来存储。

    拷贝让人混淆的,一般有这几种情况:

    • 变量有子变量的情况,如v = [ [1,2], [3,4] ], 甚至v = [ [[1,2], [3,4]], [[5,6], [7,8]] ]
    • 向列表或字典插入元素的情况,如v.append(123)且时候,v的复制品是否也会变化?
    • 向列表或字典的子变量插入元素时候,复制品是否也会变化?

    当变量有子变量的情况下:

    import copy
    
    original = [ [1,2], [3,4] ]
    
    reference  = original
    shallow = copy.copy(original) 
    deep = copy.deepcopy(original) 
    
    # -----RESULTS ------
    # Reference >>> id(reference) == id(original)
    # Shallow copy >>> id(shallow) != id(original)
    # Deep copy >>> id(deep) != id(original)
    #         but >>> id(deep[0]) == id(original[0])
    

    向列表插入元素的情况下:

    import copy
    
    original = [ [1,2], [3,4] ]
    reference  = original
    shallow = copy.copy(original) 
    deep = copy.deepcopy(original) 
    
    original.append( [5,6] )
    
    # -----RESULTS ------
    # Original >>> original == [ [1,2], [3,4], [5,6] ]
    # Reference >>> reference == [ [1,2], [3,4], [5,6] ]
    # Shallow copy >>> shallow == [ [1,2], [3,4] ]
    # Deep copy >>> deep == [ [1,2], [3,4] ]
    

    为什么浅拷贝没有变化呢?
    因为浅拷贝,只是拷贝了原变量的子变量的引用,也就是说,原变量增加的一个子变量,不会使浅拷贝增加一个引用。
    在浅拷贝后,实际上新变量shallow中存储的内容如下:

    shallow == [ address_of_[1,2], address_of_[3,4] ]
    

    也就是说这里的逻辑关系是:只有当之前的子变量[1,2][3,4]发生变动时,变量shallow才会变化。
    但是原变量original本身的扩充变化,完全和它无关了。

    使用列表和字典自带的.copy()方法:
    list和dict所自带的.copy()方法,实际上是浅拷贝。即如果new = original.copy(),那么这个new变量是浅拷贝出来的。

    相关文章

      网友评论

        本文标题:Python深拷贝、浅拷贝

        本文链接:https://www.haomeiwen.com/subject/fkfirqtx.html