在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。
浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制
深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。
深浅拷贝的作用
1,减少内存的使用
2,以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
a = {1: [1,2,3]} b = a.copy() print("a-->{}".format(a)) print("b-->{}".format(b)) ======================================== a-->{1: [1, 2, 3]} b-->{1: [1, 2, 3]} ======================================== a[1].append(4) print("a-->{}".format(a)) print("b-->{}".format(b)) ======================================== a-->{1: [1, 2, 3, 4]} b-->{1: [1, 2, 3, 4]} ========================================
1、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
2、b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
=赋值:数据完全共享
l1 = [1, 2, 3, ['aa', 'bb']] l2 = l1 l2[0]='aaa' l2[3][0]='bbb' print(l1) #['aaa', 2, 3, ['bbb', 'bb']] print(id(l1)==id(l2)) #True ======================================== ['aaa', 2, 3, ['bbb', 'bb']] True
l2 = l1 ,l1 完全赋值给l2 ,l2的内存地址与l1 相同,即内存完全指向
浅拷贝:数据半共享(复制其数据独立内存存放,但是只拷贝成功第一层)
l1 = [1,2,3,[11,22,33]] l2 = l1.copy() print(l2) #[1,2,3,[11,22,33]] l2[3][2]='aaa' print(l1) #[1, 2, 3, [11, 22, 'aaa']] print(l2) #[1, 2, 3, [11, 22, 'aaa']] l1[0]= 0 print(l1) #[0, 2, 3, [11, 22, 'aaa']] print(l2) #[1, 2, 3, [11, 22, 'aaa']] print(id(l1)==id(l2)) #Flase ======================================== [1, 2, 3, [11, 22, 33]] [1, 2, 3, [11, 22, 'aaa']] [1, 2, 3, [11, 22, 'aaa']] [0, 2, 3, [11, 22, 'aaa']] [1, 2, 3, [11, 22, 'aaa']] False
深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)
import copy l1 = [1, 2, 3, [11, 22, 33]] # l2 = copy.copy(l1) 浅拷贝 l2 = copy.deepcopy(l1) print(l1,'>>>',l2) l2[3][0] = 1111 print(l1,">>>",l2) ======================================== [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [11, 22, 33]] [1, 2, 3, [11, 22, 33]] >>> [1, 2, 3, [1111, 22, 33]]