python深浅拷贝
Posted ych9527
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python深浅拷贝相关的知识,希望对你有一定的参考价值。
文章目录
一、浅拷贝
-
概念
-
浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素尽可能是原对象中各个子对象的引用
# -*- coding: utf-8 -* list1 = [[1,2,3],(4,5,6)] list2=list(list1) print("list1 is list2 ?",list1 is list2,id(list1),id(list2)) # 判断是否是同一个元素 print(list1) print(list2) print("往list1的第一个列表元素中添加999") list1[0].append(999) print(list1) print(list2) print("给list1的第二个元组元素拼接") list1[1]+=(1,1) print(list1) print(list2) print("给list1追加一个元素") list1.append(11111) print(list1) print(list2) """ list1 is list2 ? False 4411717312 4411981056 -> 可以看到不是同一个元素 [[1, 2, 3], (4, 5, 6)] [[1, 2, 3], (4, 5, 6)] 往list1的第一个列表元素中添加999 -> 可以看到list2与list1的第一个元素,共同指向一个列表 [[1, 2, 3, 999], (4, 5, 6)] [[1, 2, 3, 999], (4, 5, 6)] 给list1的第二个元组元素拼接 -> 元组不可变,对list1第二个元组拼接,生成了新的元组,list2 没有引用新元组,因此不受影响 [[1, 2, 3, 999], (4, 5, 6, 1, 1)] [[1, 2, 3, 999], (4, 5, 6)] 给list1追加一个元素 -> list1和list2 作为整体是两个不同的对象(id不同),因此不共享内存,操作过后list2不会改变 [[1, 2, 3, 999], (4, 5, 6, 1, 1), 11111] [[1, 2, 3, 999], (4, 5, 6)] """
-
二、深拷贝
-
概念
-
重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联
-
python之中使用copy.deepcopy()来完成深拷贝
# -*- coding: utf-8 -* import copy list1 = [[1,2,3],(4,5,6)] list2=copy.deepcopy(list1) print("list1 is list2 ?",list1 is list2,id(list1),id(list2)) # 判断是否是同一个元素 print(list1) print(list2) print("往list1的第一个列表元素中添加999") list1[0].append(999) print(list1) print(list2) print("给list1的第二个元组元素拼接") list1[1]+=(1,1) print(list1) print(list2) print("给list1追加一个元素") list1.append(11111) print(list1) print(list2) """ 可以看到:不论list1 怎么操作都对list2 没有影响 list1 is list2 ? False 4351803072 4352036736 -> 不是用一个元素 [[1, 2, 3], (4, 5, 6)] [[1, 2, 3], (4, 5, 6)] 往list1的第一个列表元素中添加999 [[1, 2, 3, 999], (4, 5, 6)] [[1, 2, 3], (4, 5, 6)] 给list1的第二个元组元素拼接 [[1, 2, 3, 999], (4, 5, 6, 1, 1)] [[1, 2, 3], (4, 5, 6)] 给list1追加一个元素 [[1, 2, 3, 999], (4, 5, 6, 1, 1), 11111] [[1, 2, 3], (4, 5, 6)] """
-
三、深拷贝带来的问题
-
如果被拷贝的对象是指向自身的引用,那么程序很同一陷入无限的循环
# -*- coding: utf-8 -* import copy list1 = [1] list1.append(list1) # 陷入不断的循环 print(list1) list2 = copy.deepcopy(list1) #拷贝,但是没有栈溢出 print(list2) """ [1, [...]] [1, [...]] """
-
上面list1列表中有指向自身的引用,因此list1是一个无限嵌套的列表,但是深度拷贝到list2之后程序没有栈溢出,这是因为深度拷贝函数 deepcopy 中会维护一个字典,记录已经拷贝的对象与其 ID。拷贝过程中,如果字典里已经存储了将要拷贝的对象,则会从字典直接返回,而不是继续调用深拷贝函数
-
deepcopy部分源码
def deepcopy(x, memo=None, _nil=[]): """Deep copy operation on arbitrary Python objects. See the module's __doc__ string for more info. """ if memo is None: memo = d = id(x) # 查询被拷贝对象 x 的 id y = memo.get(d, _nil) # 查询字典里是否已经存储了该对象 if y is not _nil: return y # 如果字典里已经存储了将要拷贝的对象,则直接返回 ...
-
以上是关于python深浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章