欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python中的shallow copy 和 deep copy

程序员文章站 2022-06-03 14:25:24
...
  • Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块。
  • 1.copy.copy 浅拷贝 只拷贝父对象
  • 2.copy.deepcopy 深拷贝 拷贝父对象及其子对象
  • 3.例子解读:

    >>>x=5
    >>>y=x
    >>>id(x)==id(y)
    True
    
    #刚开始y和x是相同的地址,现在对y赋值
    
    >>>y=10
    >>>id(x)==id(y)
    False
    
    #赋值后y将会有新的地址
    
    
    #若是
    
    >>>x=y#结果就又不一样了

    所以,python默认的是拷贝是对变量的引用,要实现真正的拷贝需要调用copy模块

    列表的拷贝

    >>> colours1 = ["red", "blue"]
    >>> colours2 = colours1
    >>> print(colours1)
    ['red', 'blue']
    >>> print(colours2)
    ['red', 'blue']
    >>> print(id(colours1),id(colours2))
    43444416 43444416
    >>> colours2 = ["rouge", "vert"]
    >>> print(colours1)
    ['red', 'blue']
    >>> print(colours2)
    ['rouge', 'vert']
    >>> print(id(colours1),id(colours2))
    43444416 43444200
    >>> 

    整体改变列表的时候,给引用变量生成了新的地址,再来看改变其中一个元素时,

    >>> colours1 = ["red", "blue"]
    >>> colours2 = colours1
    >>> print(id(colours1),id(colours2))
    14603760 14603760
    >>> colours2[1] = "green"
    >>> print(id(colours1),id(colours2))
    14603760 14603760
    >>> print(colours1)
    ['red', 'green']
    >>> print(colours2)
    ['red', 'green']
    >>> 

    改变引用时,原来变量的值也被改变。可以使用切片运算来进行列表的浅拷贝克服这个问题,

    >>> list1 = ['a','b','c','d']
    >>> list2 = list1[:]
    >>> id(list1)==id(list2)
    False
    >>> list2[1] = 'x'
    >>> print(list2)
    ['a', 'x', 'c', 'd']
    >>> print(list1)
    ['a', 'b', 'c', 'd']
    >>> 

    但是使用切片方法,在列表中包含子列表的时候,新的问题就又出现了,

    >>> lst1 = ['a','b',['ab','ba']]
    >>> lst2 = lst1[:]
    >>> id(lst1)==id(lst1)
    False
    >>> lst2[0] = 'c'
    >>> print(lst1)
    ['a', 'b', ['ab', 'ba']]
    >>> print(lst2)
    ['c', 'b', ['ab', 'ba']]
    
    #但是,若对list2中子列表中值进行修改,list1将还是会受到影响
    
    >>>lst2[2][1]='d'
    >>>print(lst2)
    ['c','b',['ab','d']]
    >>>print(lst1)
    ['a','b',['ab','d']]

    浅拷贝只对父列表进行了拷贝,没有对子列表进行拷贝。如图,

    python中的shallow copy 和 deep copy

    为了解决这个问题,实现列表的完全拷贝,考虑使用copy模块的deepcopy函数,

    >>> from copy import deepcopy
    >>> 
    >>> lst1 = ['a','b',['ab','ba']]
    >>> 
    >>> lst2 = deepcopy(lst1)
    >>> 
    >>> lst1
    ['a', 'b', ['ab', 'ba']]
    >>> lst2
    ['a', 'b', ['ab', 'ba']]
    >>> id(lst1)==id(lst2)
    False
    >>>id(lst1[2][0])==id(lst2[2][0])
    False
    >>> lst2[2][1] = "d"
    >>> lst2[0] = "c"
    >>> print(lst1)
    ['a', 'b', ['ab', 'ba']]
    >>> print(lst2)
    ['c', 'b', ['ab', 'd']]
    >>> 

    其存储示意图如下:

    python中的shallow copy 和 deep copy

    测验:

    >>> import copy
    >>> a = [1,2,3,4,['a','b']]  #原始对象
    >>> b = a  #赋值,传对象的引用
    >>> c = copy.copy(a)
    >>> d = copy.deepcopy(a)
    >>> e = a[:]
    >>> a.append(5)
    >>> a[4].append('c')
    >>> print 'a=',a
    a= [1, 2, 3, 4, ['a', 'b', 'c'], 5]
    >>> print 'b=',b
    b= [1, 2, 3, 4, ['a', 'b', 'c'], 5] #引用
    >>> print 'c=',c
    c= [1, 2, 3, 4, ['a', 'b', 'c']]  #浅拷贝
    >>> print 'd=',d
    d= [1, 2, 3, 4, ['a', 'b']]      #深拷贝
    >>> print 'e'=,e
    e= [1, 2, 3, 4, ['a', 'b', 'c']]  #浅拷贝

  • refer

[1] https://www.python-course.eu/python3_deep_copy.php

[2] https://*.com/questions/17873384/deep-copy-a-list-in-python

相关标签: python copy