浅拷贝
是指复制对象本身,但不
会复制
对象内部
的嵌套对象
。换句话说,浅拷贝
会创建
一个新
的对象,但是新对象
中的元素
是原始对象元素
的引用
(即指向同一块内存地址
)。因此,若原始对象中的元素是可变
对象,修改
这些元素会影响
到原始对象
和拷贝对象
。
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}")
l2
是l1
的浅拷贝
,是两个不同的对象,两者内存地址不同。
注意:拷贝的列表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']
深拷贝
是指复制对象
及其内部所有嵌套对象
。深拷贝
会递归地复制每个
对象,不仅复制对象本身,还复制所有嵌套
的子对象,这样原始对象
和拷贝对象
完全独立
,修改其中一个不会影响另一个
。参考代码如下:
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']
浅拷贝
:复制对象,但嵌套对象
仍然指向相同的内存地址。
深拷贝
:递归复制对象以及所有嵌套的子对象,确保原始对象
和拷贝对象
之间完全独立
。
浅拷贝
:适用于嵌套对象不需要被修改
时。
深拷贝
:适用于嵌套对象也需要被独立复制
,确保修改拷贝
时不影响
原始对象。
感谢浏览,一起学习!