深拷贝和浅拷贝的主要区别就是拷贝对象的深浅,Python中一切皆为对象,当我们想要拷贝列表时,会出现列表中还包括一个列表的形式(比如:[ 1, 2, 3 , [4, 5, 6] ] ),如果只是单纯的拷贝一层列表,使用浅拷贝即可,如果想把列表中包含的子列表也拷贝来,就需要使用深拷贝。
下面来看一下深浅拷贝的定义以及图解。
浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用,多个变量共用一份数据。
深拷贝:会连子对象的内容也全部拷贝一份,对子对象的修改不会改变源对象,多个变量独立的使用各自的数据,不共用。
使用深浅拷贝涉及到的内置函数:
- 导入copy模块;
- 浅拷贝:使用copy()函数;
- 深拷贝:使用deepcopy()函数;
下面我们假设对列表 a=[ 10, 20, [5,6] ] 来进行拷贝,显然其中[5,6]是a的子对象。
浅拷贝:类似于树结构,只拷贝最上面的父根节点,不拷贝子根节点。
它指向了[5,6]这个子对象,因此在b中对子对象修改的话,a中的子对象[5,6]也会相应改变。
可以看到在使用了append方法后,a和b的子对象是同时变化的,a和b中非子对象内容不变。
深拷贝:把所有的东西都拷贝一份,相当于父根节点和子根节点都拷贝,自己单独具有了一份就不会修改之前拷贝的那份。
在使用浅拷贝时,b中子对象改变了,a中子对象也改变了,但是如果我不想在修改b中的子列表而影响了原本的a子列表,那么就可以使用深拷贝。
可以很清楚看到,在使用了深拷贝之后,在b中修改子对象[5,6],a中的[5,6]不变。
完整代码,大家可以拷贝去自己试一试呀!
import copy
def test_copy():
"""测试浅拷贝"""
a = [10,20,[5,6]]
b = copy.copy(a)
b.append(30)
b[2].append(7)
print("a:",a)
print("b:",b)
def test_deep_copy():
"""测试深拷贝"""
a = [10,20,[5,6]]
b = copy.deepcopy(a)
b.append(30)
b[2].append(7)
print("a:",a)
print("b:",b)
test_copy()
test_deep_copy()