python 深拷贝、浅拷贝

时间:2022-06-01 20:53:06

深拷贝和浅拷贝针对的是可变类型而言,对于不可变类型,不存在这个问题,当修改不可变对象时,会重新开辟一块内存空间,而可变对象,是在原内存空间修改。

a = "asdas"
b = a
print(id(a))
print(id(b))
a = "qqq"
print(id(a))
print(id(b))
print(a, b)

输出结果为:

2219925075256
2219925075256
2219925075424
2219925075256
qqq asdas

对于直接赋值(=)、深拷贝、浅拷贝

直接赋值是将原对象的引用赋值给变量,两个对象都指向同一块内存地址。

a = [1, 2, 3, [4, 5, 6]]
b = a
print(id(a))
print(id(b))
a[0] = "qqq"
print(id(a))
print(id(b))
print(a, b)

输出结果:

2006021726920
2006021726920
2006021726920
2006021726920
['qqq', 2, 3, [4, 5, 6]] ['qqq', 2, 3, [4, 5, 6]]

浅拷贝是将原对象重新拷贝一份赋值给变量,两个对象指向不同的内存地址,但是,对于原对象的子元素如果是可变对象,则复制的内存地址,因此,如果原对象的子元素改变,新对象的子元素也会改变。

import copy

a = [1, 2, 3, [4, 5, 6]]
b = copy.copy(a)
print(id(a))
print(id(b))
a[0] = "qqq"
print(id(a))
print(id(b))
print(a, b)

输出结果为:

2099093564872
2099093658184
2099093564872
2099093658184
['qqq', 2, 3, [4, 5, 6]] [1, 2, 3, [4, 5, 6]]

当修改子元素时:

import copy

a = [1, 2, 3, [4, 5, 6]]
b = copy.copy(a)
print("a地址:", id(a))
print("b地址:", id(b))
print("a子元素:", id(a[3]))
print("b子元素:", id(b[3]))
a[3][1] = "qqq"
print(a, b)

输出结果为:

a地址: 1256840228360
b地址: 1256840321928
a子元素: 1256840163912
b子元素: 1256840163912
[1, 2, 3, [4, 'qqq', 6]] [1, 2, 3, [4, 'qqq', 6]]

深拷贝则是完完全全重新复制一份原对象赋值给变量,两个对象之间毫无关系了。

import copy

a = [1, 2, 3, [4, 5, 6]]
b = copy.deepcopy(a)
print("a地址:", id(a))
print("b地址:", id(b))
print("a子元素:", id(a[3]))
print("b子元素:", id(b[3]))
a[3][1] = "qqq"
print(a, b)

输出结果为:

a地址: 2025980030472
b地址: 2025980124104
a子元素: 2025979966024
b子元素: 2025980123080
[1, 2, 3, [4, 'qqq', 6]] [1, 2, 3, [4, 5, 6]]