Python深浅拷贝
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
针对该列表l1=['a','b','c',['d','e','f']]
一般有三种方法,分别为:拷贝(赋值)、浅拷贝、深拷贝
注意:拷贝/浅拷贝/深拷贝都是针对可变类型数据而言的,id不变值可变,即在原值的基础上修改,则为可变数据类型;值变id也变,即重新申请一个空间放入新值,则为不可变数据类型。
一、拷贝(赋值)
如果l2是l1的拷贝对象,则l1内部的任何数据类型的元素变化,则l2内部的元素也会跟着改变,因为可变类型值变id不变。
lt = [1, 2, 3, 4, 5]
lt2 = lt
lt.append(6)
print(lt)
# 因为列表是可变类型, 所以lt的值变化,lt2值也会跟着变化
print(lt2)
print(id(lt))
print(id(lt2))
结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
2304711549576
2304711549576
二、浅拷贝
如果l2是l1的浅拷贝对象,则l1内的不可变元素发生了改变,l2不变;如果l1内的可变元素发生了改变,则l2会跟着改变。
-
添加值不发生变化
import copy lt = [100, 200, 300, [400, 500, 600]] lt2 = copy.copy(lt) # 没有变化情况 lt.append(700) print(lt) print(lt2)
结果:
[100, 200, 300, [400, 500, 600], 700]
[100, 200, 300, [400, 500, 600]] -
添加值发生变化
import copy lt = [100, 200, 300, [400, 500, 600]] lt2 = copy.copy(lt) # 变化情况 print('id(lt)',id(lt)) print('id(lt[0])', id(lt[0])) print('id(lt[1])', id(lt[1])) print('id(lt[2])', id(lt[2])) print('id(lt[3])', id(lt[3])) print('*' * 50) print('id(lt2)',id(lt2)) print('id(lt2[0])', id(lt2[0])) print('id(lt2[1])', id(lt2[1])) print('id(lt2[2])', id(lt2[2])) print('id(lt2[3])', id(lt2[3])) print('*' * 50) lt[-1].append(700) print(lt) print(lt2)
结果:(浅拷贝,lt和lt2的id不一样,lt[-1]和lt[-1]一样)
id(lt) 1520433324744
id(lt[0]) 140712889544624
id(lt[1]) 140712889547824
id(lt[2]) 1520433550832
id(lt[3]) 1520433324680
id(lt2) 1520715912264
id(lt2[0]) 140712889544624
id(lt2[1]) 140712889547824
id(lt2[2]) 1520433550832
id(lt2[3]) 1520433324680
[100, 200, 300, [400, 500, 600, 700]]
[100, 200, 300, [400, 500, 600, 700]]
三、深拷贝
如果l2是l1的深拷贝对象,则l1内的不可变元素发生了改变,l2不变;如果l1内的可变元素发生了改变,l2也不会变,即l2永远不会因为l1的变化而变化。
import copy
lt = [100, 200, 300, [400, 500, 600]]
lt2 = copy.deepcopy(lt)
print('id(lt)',id(lt))
print('id(lt[0])', id(lt[0]))
print('id(lt[1])', id(lt[1]))
print('id(lt[2])', id(lt[2]))
print('id(lt[3])', id(lt[3]))
print('*' * 50)
print('id(lt2)',id(lt2))
print('id(lt2[0])', id(lt2[0]))
print('id(lt2[1])', id(lt2[1]))
print('id(lt2[2])', id(lt2[2]))
print('id(lt2[3])', id(lt2[3]))
print('*' * 50)
lt.append(70)
print(lt)
print(lt2)
print("*" * 50)
lt2[-1].append(7000)
print(lt)
print(lt2)
结果:
id(lt) 1585269859016
id(lt[0]) 140712889544624
id(lt[1]) 140712889547824
id(lt[2]) 1585270085104
id(lt[3]) 1585269858952
id(lt2) 1585552380680
id(lt2[0]) 140712889544624
id(lt2[1]) 140712889547824
id(lt2[2]) 1585270085104
id(lt2[3]) 1585299572040
[100, 200, 300, [400, 500, 600], 70]
[100, 200, 300, [400, 500, 600]]
[100, 200, 300, [400, 500, 600], 70]
[100, 200, 300, [400, 500, 600, 7000]]
四、总结
- 拷贝:当lt2为lt的拷贝对象时, lt内可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化(简单赋值)
- 浅拷贝:当lt2为lt的拷贝对象时,lt内可变类型变化,lt2变化;lt内不可变类型变化,lt2不变化(copy.copy())
- 深拷贝:当lt2为lt的拷贝对象时, lt内的可变类型变化,lt2不变化;lt内不可变类型变化,lt2不变化(copy.deepcopy())
注:拷贝/浅拷贝/深拷贝 只针对可变数据类型