Python —— 深拷贝和浅拷贝

Python —— 深拷贝和浅拷贝

  • 浅拷贝 —— Shallow Copy
  • 深拷贝 —— Deep Copy
  • 总结
  • 常见的应用场景

浅拷贝 —— Shallow Copy

浅拷贝是指复制对象本身,但复制对象内部嵌套对象。换句话说,浅拷贝创建一个的对象,但是新对象中的元素原始对象元素引用(即指向同一块内存地址)。因此,若原始对象中的元素是可变对象,修改这些元素会影响原始对象拷贝对象

s = "abcdef123456"
l1 = list(s) # 把字符串变成列表
l2 = l1.copy() # list 数据类型自带的浅拷贝
print(f"l1 = {l1}\nl2 = {l2}")
print(f"id(l1) = {id(l1)}\nid(l2) = {id(l2)}") # 打印两者内存地址
print(f"id(l1[3]) = {id(l1[3])}\nid(l2[3]) = {id(l2[3])}") # 每一个元素扔指向原始字符d,所以id一致。
l1[0] = 'x' # l1、l2中的元素都是不可变对象,故改变拷贝对象,不会影响原对象。
print(f"l1 = {l1}")
print(f"l2 = {l2}")
l2[0] = 'y'
print(f"l1 = {l1}")
print(f"l2 = {l2}")

l2l1浅拷贝,是两个不同的对象,两者内存地址不同。
注意:拷贝的列表l2中每个元素仍然指向原始字符(它们是字符串,字符串是不可变的,所以不会受到影响)。运行结果如下:

l1 = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
l2 = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
id(l1) = 140376061742848
id(l2) = 140376061990144
id(l1[3]) = 140376062729520
id(l2[3]) = 140376062729520
l1 = [‘x’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
l2 = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
l1 = [‘x’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
l2 = [‘y’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]

嵌套可变对象如果被修改,会影响列表。参考代码如下:

l1 = [123,"abc", ["1a2b", 666], 'x']
l2 = l1.copy()
print(f"l1 = {l1}") # l1 = [123, 'abc', ['1a2b', 666], 'x']
print(f"l2 = {l2}") # l2 = [123, 'abc', ['1a2b', 666], 'x']
print(f"id(l1) = {id(l1)}") # id(l1) = 139777658463680
print(f"id(l2) = {id(l2)}") # id(l2) = 139777658164800
print(f"id(l1[2]) = {id(l1[2])}") # id(l1[2]) = 139777658463488
print(f"id(l2[2]) = {id(l2[2])}") # id(l2[2]) = 139777658463488
print(f"id(l1[0]) = {id(l1[0])}") # id(l1[0]) = 9788800
print(f"id(l2[0]) = {id(l2[0])}") # id(l2[0]) = 9788800
l1[2][0] = "aaa"
print(f"l1 = {l1}") # l1 = [123, 'abc', ['aaa', 666], 'x']
print(f"l2 = {l2}") # l2 = [123, 'abc', ['aaa', 666], 'x']
l2[2][1] = 888
print(f"l1 = {l1}") # l1 = [123, 'abc', ['aaa', 888], 'x']
print(f"l2 = {l2}") # l2 = [123, 'abc', ['aaa', 888], 'x']

深拷贝 —— Deep Copy

深拷贝是指复制对象及其内部所有嵌套对象深拷贝会递归地复制每个对象,不仅复制对象本身,还复制所有嵌套的子对象,这样原始对象拷贝对象完全独立修改其中一个不会影响另一个。参考代码如下:

import copy # 需要用到copy模块
# copy模块里面也有浅拷贝函数 copy.copy() 使用所有数据类型

t1 = [123,"abc", ["1a2b", 666], 'x']
t2 = copy.deepcopy(t1)
print(f"t1 = {t1}") # t1 = [123, 'abc', ['1a2b', 666], 'x']
print(f"t2 = {t2}") # t2 = [123, 'abc', ['1a2b', 666], 'x']
print(f"id(t1) = {id(t1)}") # id(t1) = 140355517295168
print(f"id(t2) = {id(t2)}") # id(t2) = 140355517406720
print(f"id(t1[2][0]) = {id(t1[2][1])}") # id(t1[2][0]) = 140355517792112
print(f"id(t2[2][0]) = {id(t2[2][1])}") # id(t2[2][0]) = 140355517792112 不可变数据,所以两者id一样
t1[2][0] = 111
print(f"t1 = {t1}") # t1 = [123, 'abc', [111, 666], 'x']
print(f"t2 = {t2}") # t2 = [123, 'abc', ['1a2b', 666], 'x']
t2[2][1] = "xxx"
print(f"t1 = {t1}") # t1 = [123, 'abc', [111, 666], 'x']
print(f"t2 = {t2}") # t2 = [123, 'abc', ['1a2b', 'xxx'], 'x']

总结

浅拷贝:复制对象,但嵌套对象仍然指向相同的内存地址。
深拷贝:递归复制对象以及所有嵌套的子对象,确保原始对象拷贝对象之间完全独立

常见的应用场景

浅拷贝:适用于嵌套对象不需要被修改时。
深拷贝:适用于嵌套对象也需要被独立复制,确保修改拷贝不影响原始对象。

感谢浏览,一起学习!

你可能感兴趣的:(python,开发语言,学习)