最直观的理解就是:
1.深拷贝,拷贝的程度深,自己新开辟了一块内存,将被拷贝内容全部拷贝过来了;
2.浅拷贝,拷贝的程度浅,只拷贝原数据的首地址,然后通过原数据的首地址,去获取内容。
两者的优缺点对比:
(1)深拷贝拷贝程度高,将原数据复制到新的内存空间中。改变拷贝后的内容不影响原数据内容。但是深拷贝耗时长,且占用内存空间。
(2)浅拷贝拷贝程度低,只复制原数据的地址。其实是将副本的地址指向原数据地址。修改副本内容,是通过当前地址指向原数据地址,去修改。所以修改副本内容会影响到原数据内容。但是浅拷贝耗时短,占用内存空间少。
有一层数据类型,且数据类型时可变数据类型,例如:列表、字典
import copy a = [1,2,3] b = copy.copy(a) print(a) # [1, 2, 3] print(b) # [1, 2, 3] # 地址不一致 print(id(a)) # 1579517559496 print(id(b)) # 1579517560200 a.append(4) print(a) # [1, 2, 3, 4] print(b) # [1, 2, 3]
有一层数据类型,且数据类型时不可变数据类型,例如:元组、字符串
import copy a = (6,7,8) b = copy.copy(a) print(a) # (6, 7, 8) print(b) # (6, 7, 8) # 地址一致 print(id(a)) # 2593238617544 print(id(b)) # 2593238617544
有两层数据类型,外层为可变数据类型,内层为可变数据类型
import copy a = [1,2] b = [3,4] c = [a,b] d = copy.copy(c) print(c) [[1, 2], [3, 4]] print(d) [[1, 2], [3, 4]] print(id(c)) # 2280002580808 # 外层地址改变 print(id(d)) # 2280002580744 print(id(a)) # 2280002580936 print(id(b)) # 2280002581768 # 内层地址不变 print(id(c[0])) # 2280002580936 print(id(c[1])) # 2280002581768 print(id(d[0])) # 2280002580936 print(id(d[1])) # 2280002581768
有两层数据类型,外层为可变数据类型,内层为不可变数据类型
import copy a = (7,8) b = (9,0) c = [a,b] d = copy.copy(c) print(c) # [(7, 8), (9, 0)] print(d) # [(7, 8), (9, 0)] print(id(a)) # 2064778398344 print(id(b)) # 2064778398472 print(id(c)) # 2064778597512 # 外层地址改变 print(id(d)) # 2064778598856 # 内层地址不变 print(id(c[0])) # 2064778398344 print(id(d[0])) # 2064778398344 print(id(c[1])) # 2064778398472 print(id(d[1])) # 2064778398472
有两层数据类型,外层为不可变数据类型,内层为不可变数据类型
import copy a = (1,2) b = (3,4) c = (a,b) d = copy.copy(c) print(c) # ((1, 2), (3, 4)) print(d) # ((1, 2), (3, 4)) print(id(a)) # 1933760334536 print(id(b)) # 1933760334664 # 外层地址不变 print(id(c)) # 1933760521736 print(id(d)) # 1933760521736 # 内层地址不变 print(id(c[0])) # 1933760334536 print(id(c[1])) # 1933760334664 print(id(d[0])) # 1933760334536 print(id(d[1])) # 1933760334664
有两层数据类型,外层为不可变数据类型,内层为可变数据类型
import copy a = [1,2] b = [3,4] c = (a,b) d = copy.copy(c) print(c) # ([1, 2], [3, 4]) print(d) # ([1, 2], [3, 4]) print(id(a)) # 2098312709128 print(id(b)) # 2098312709960 # 外层地址不变 print(id(c)) # 2098312709512 print(id(d)) # 2098312709512 # 内层地址不变 print(id(c[0])) # 2098312709128 print(id(c[1])) # 2098312709960 print(id(d[0])) # 2098312709128 print(id(d[1])) # 2098312709960
有一层数据类型,且数据类型时可变数据类型,例如:列表、字典
import copy a = [1,2] b = copy.deepcopy(a) print(a) # [1, 2] print(b) # [1, 2] # 地址发生改变 print(id(a)) # 2712262157064 print(id(b)) # 2712262157832
有一层数据类型,且数据类型时不可变数据类型,例如:元组、字符串
import copy a = (1,2) b = copy.deepcopy(a) print(a) # (1, 2) print(b) # (1, 2) # 地址未改变 print(id(a)) # 2372779051400 print(id(b)) # 2372779051400
有两层数据类型,外层为可变数据类型,内层为可变数据类型
import copy a = [1,2] b = [3,4] c = [a,b] d = copy.deepcopy(c) print(c) # [[1, 2], [3, 4]] print(d) # [[1, 2], [3, 4]] print(id(a)) # 2044073358024 print(id(b)) # 2044073358984 # 外层地址不变 print(id(c)) # 2044073357896 print(id(d)) # 2044073358856 # 内层地址改变 print(id(c[0])) # 2044073358024 print(id(c[1])) # 2044073358984 print(id(d[0])) # 2044073357832 print(id(d[1])) # 2044072936328
有两层数据类型,外层为可变数据类型,内层为不可变数据类型
import copy a = (1,2) b = (3,4) c = [a,b] d = copy.deepcopy(c) print(c) # [(1, 2), (3, 4)] print(d) # [(1, 2), (3, 4)] print(id(a)) # 2197363967752 print(id(b)) # 2197363967880 # 外层地址改变 print(id(c)) # 2197364167112 print(id(d)) # 2197364168520 # 内层地址不变 print(id(c[0])) # 2197363967752 print(id(c[1])) # 2197363967880 print(id(d[0])) # 2197363967752 print(id(d[1])) # 2197363967880
有两层数据类型,外层为不可变数据类型,内层为不可变数据类型
import copy a = (1,2) b = (3,4) c = (a,b) d = copy.deepcopy(c) print(c) # ((1, 2), (3, 4)) print(d) # ((1, 2), (3, 4)) print(id(a)) # 2582331737992 print(id(b)) # 2582331738120 # 外层地址不变 print(id(c)) # 2582331942280 print(id(d)) # 2582331942280 # 内层地址不变 print(id(c[0])) # 2582331737992 print(id(c[1])) # 2582331738120 print(id(d[0])) # 2582331737992 print(id(d[1])) # 2582331738120
有两层数据类型,外层为不可变数据类型,内层为可变数据类型
import copy a = [1,2] b = [3,4] c = (a,b) d = copy.deepcopy(c) print(c) # ([1, 2], [3, 4]) print(d) # ([1, 2], [3, 4]) print(id(a)) # 1404187259528 print(id(b)) # 1404187260424 # 外层地址改变 print(id(c)) # 1404187259976 print(id(d)) # 1404187259784 # 内层地址改变 print(id(c[0])) # 1404187259528 print(id(c[1])) # 1404187260424 print(id(d[0])) # 1404187259336 print(id(d[1])) # 1404187059400
浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
当内层为可变数据类型时,深拷贝后内层外层地址均发生改变。当内层为不可变数据类型时,外层不管是可变还是不可变数据类型,使用深拷贝,都不会改变内层地址,只会改变外层地址。
使用浅拷贝是只能在外层数据类型为可变数据类型时,才能改变外层地址。而内层地址,无论是否为可变数据类型还是不可变数据类型,使用浅拷贝都不会改变内层数据类型地址。