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  

参考:

https://www.yuque.com/docs/share/abfa1a00-0cd9-4a4f-bc20-55ea65249c72

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值