深拷贝与浅拷贝

在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。

浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。目标对象和源对象指向的内存空间是同一块空间,浅拷贝只是一种简单的拷贝,让几个对象公用一个内存

深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响

python深拷贝浅拷贝 python深拷贝与浅拷贝区别_浅拷贝

深浅拷贝的作用

1,减少内存的使用
2,以后在做数据的清洗、修改或者入库的时候,对原数据进行复制一份,以防数据修改之后,找不到原数据。

浅拷贝

1、赋值

a = [1, 2, 3, ['a', 'c', 'd']]
b = a
a.append(9)
b.append(8)
print('我是a:%s' % a)
print('我是b:%s' % b)

结果 

我是a:[1, 2, 3, ['a', 'c', 'd'], 9, 8]
我是b:[1, 2, 3, ['a', 'c', 'd'], 9, 8]

这里直接赋值,默认浅拷贝传递对象的引用,原始列表改变,被赋值的b也会做相同的改变

2、copy拷贝

a = [1, 2, 3, ['a', 'b', 'c']]
b = copy.copy(a)
a.append(9)
a[3].append('d')
print('我是a:%s' % a)
print('我是b:%s' % b)

结果 

我是a:[1, 2, 3, ['a', 'b', 'c', 'd'], 9]
 我是b:[1, 2, 3, ['a', 'b', 'c', 'd']]

copy浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变

第三行里a在最后追加了一个9,最后的结果b的最后却没有被追加

第四行里a下标3在最后追加了一个‘d’,最后的结果它们都被追加了一个d,因为a[3]是a b的共享子对象。

python深拷贝浅拷贝 python深拷贝与浅拷贝区别_python_02

总结

浅拷贝有两种方式,第一种是直接赋值,第二种是copy拷贝

第一种赋值的方式它们指向同一个地址,所以当原目标被赋值目标,它们其中一个被改变,它们两个的值都会改变

第二种copy拷贝它们指向不同的地址,所以当原目标被赋值目标,它们其中一个被改变,另一个的值不会改变。因为没有拷贝子对象,所以原始数据改变,子对象会改变

深拷贝

a = [1, 2, 3, ['a', 'b']]
b = copy.deepcopy(a)
a.append(5)
a[3].append('c')
print(a)
print(b)

结果 

[1, 2, 3, ['a', 'b', 'c'], 5]
 [1, 2, 3, ['a', 'b']]

深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变。(a b的子对象并不共享。

所以改变其中一个的子对象并不会对另一个子对象有任何影响。

python深拷贝浅拷贝 python深拷贝与浅拷贝区别_python深拷贝浅拷贝_03

 

总结

深拷贝有一种方式,用deepcopy(深度复制)

深拷贝的原目标被赋值目标都会有不同的地址值,它们映射的地址值不同。并且它们的子对象也是被区分开的,不是公用一个子对象