Python 深浅复制

Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变的或包含可变项的容器,有时需要一个副本,所以可以改变一个副本而不改变另一个。


浅复制

将创建一个新对象,但它包含的是对原始对象包含的项的引用。

a = [] 
b = list(a)
c=a.copy()
d = copy.copy(a)

深复制

创建一个新对象,并且递归的复制他包含的所有对象。

import copy 
b = []
a = copy.deepcopy(b)

当原始对象中包含可变对象a,浅复制仅仅复制对a的引用

这时,如果a的值更改,那么相应新对象中a的值也会更改

>>> a=[1,2,3]
>>> b = {'x':['a','b'], 'y':a}    #字典b的value都是可变对象

>>> c = copy.copy(b)        #浅复制
>>> d = copy.deepcopy(b)    #深复制

>>> a.pop()                #修改a
3
>>> b
{'x': ['a', 'b'], 'y': [1, 2]}    #原始对象b改变
>>> c
{'x': ['a', 'b'], 'y': [1, 2]}    #浅复制c同样发生改变
>>> d
{'x': ['a', 'b'], 'y': [1, 2, 3]}    #深复制d不变

>>> b['x'].append('c')
>>> b
{'x': ['a', 'b', 'c'], 'y': [1, 2]}
>>> c
{'x': ['a', 'b', 'c'], 'y': [1, 2]}
>>> d
{'x': ['a', 'b'], 'y': [1, 2, 3]} 

使用内置函数id()来查看对象的标识

                        标识相当于内存中对象中的地址

>>> id(a)
50285512
>>> id(b['y'])
50285512
>>> id(c['y'])        
50285512
>>> id(d['y'])
49946056

可以发现原始对象b['y']和浅复制对象c['y']的标识相同,和a引用同一个值,而深复制对象d['y']引用的是一个新的值


        所以将a添加到浅复制对象c['y']中会导致递归引用

>>> a
[1, 2]
>>> c['y'].append(a)
>>> c
{'x': ['a', 'b', 'c'], 'y': [1, 2, [...]]}    #c['y']出现递归引用
>>> a.pop()        #删除a中对a的引用
[1, 2]
>>> d
{'x': ['a', 'b'], 'y': [1, 2, 3, [1, 2]]}    #d['y']和a引用的不是一个值,所以不会发生诋毁引用

实现简单的深浅复制

def mycopy(x):
    '''浅复制函数,接受list,tuple,set,dict类型的参数'''
    types = {list,tuple,set}
    cls = type(x)
    if cls in types:
        n = [item for item in x]
        return cls(n)
    elif cls is dict:
        return {key:value for key,value in x.items()}
    raise TypeError






Python,深复制复制是两种不同的复制方式。 复制是创建一个新对象,这个对象有着原始对象的引用,但是它并不复制原始对象的数据。在Python,使用copy()方法可以实现复制。 深复制是创建一个新对象,这个对象有着原始对象数据的完整复制。在Python,使用deepcopy()方法可以实现深复制。 需要注意的是,对于不可变对象(如字符串、数字、元组等),无论是深复制还是复制都是一样的结果。而对于可变对象(如列表、字典等),深复制复制整个对象,包括对象内部的所有数据,而复制只会复制对象的引用,而不会复制对象内部的数据。 下面是一个例子,展示了复制和深复制的区别: ``` import copy # 复制 a = [1, 2, [3, 4]] b = copy.copy(a) a[2][0] = 5 print(a) # [1, 2, [5, 4]] print(b) # [1, 2, [5, 4]] # 深复制 c = copy.deepcopy(a) a[2][1] = 6 print(a) # [1, 2, [5, 6]] print(c) # [1, 2, [5, 4]] ``` 在上面的例子,我们首先使用复制创建了一个列表b,然后修改了a列表的一个元素。可以看到,由于复制复制了对象的引用,所以修改a列表的元素同时也修改了b列表的元素。 然后我们使用深复制创建了一个列表c,再次修改了a列表的一个元素。可以看到,由于深复制复制的是整个对象,所以修改a列表的元素并没有影响到c列表的元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值