浅拷贝,深拷贝
原文链接
提到拷贝,主要使用赋值、copy模块、列表切片、字典copy()来实现拷贝
# 赋值
# 赋值产生的拷贝是浅拷贝,共享地址。
# 改变任意一个对象中元素的值,会同时影响拷贝对象,
# 当前对象怎么变,拷贝的对象就跟着怎么变
list1 = [1,2,3,4,5]
list2 = list1
list2[0] = 100
print(list1,id(list1))
print(list2,id(list2))
# [100, 2, 3, 4, 5] 2166018012616
# [100, 2, 3, 4, 5] 2166018012616
list1 = [[1,2,3],2,3,4,5]
list2 = list1
list2[0][0] = 100
print(list1,id(list1))
print(list2,id(list2))
# [[100, 2, 3], 2, 3, 4, 5] 1932839048904
# [[100, 2, 3], 2, 3, 4, 5] 1932839048904
import copy # 使用copy模块
# 浅拷贝
# 对于不可变类型:数字、字符串、元组, 浅拷贝仅仅是地址,
# 即就是使用相同的地址,引用相同的地址id,不会开辟新空间。
iNum = 1
iNewNum = copy.copy(iNum)
print(iNum,id(iNum)) # 1 1969923168
print(iNewNum,id(iNewNum)) # 1 1969923168
# 对于可变类型:列表、字典、集合,浅拷贝会开辟新的空间地址
# (仅仅是最外层开辟了新的空间,里层的元素地址还是相同的)
lstchild = ['a','b']
lst = [lstchild, 1, 2, 3]
lstCopy = copy.copy(lst)
print(lst,id(lst)) # [['a', 'b'], 1, 2, 3] 2419428511048
print(lstCopy,id(lstCopy)) # [['a', 'b'], 1, 2, 3] 2419428455688
print(id(lst[0])) # 1539324376328
print(id(lstCopy[0])) # 1539324376328
# 可以看出浅拷贝前后两个列表的地址是不同的,但是子元素列表的地址是相同的。
# 由上面可知,浅拷贝后,改变任意一个对象中不可变类型的元素的值,
# 只有当前对象受影响,不影响拷贝的对象;
# 改变任意一个对象中为可变类型的元素的值,会同时影响拷贝对象的。
lst[0][0] = 'aa'
lst[1] = 11
print(lst) # [['aa', 'b'], 11, 2, 3]
print(lstCopy) # [['aa', 'b'], 1, 2, 3]
# 改变lstCopy同理
# 注意:若改变任意一个对象中一个可变类型(整个,不是其中的某个元素),
# 也只会影响当前对象。
lst[0] = "ab"
print(lst) # ['ab', 11, 2, 3]
print(lstCopy) # [['aa', 'b'], 1, 2, 3]
# 深拷贝
# copy.deepcopy()除了外层拷贝,还对子元素也进行了拷贝(本质上递归浅拷贝),
# 原对象和拷贝对象地址不同,所有的元素地址也不同
import copy
lstchild = ['a','b']
lst = [lstchild, 1, 2, 3]
lstCopy = copy.deepcopy(lst)
print(lst,id(lst)) # [['a', 'b'], 1, 2, 3] 2096824546824
print(lstCopy,id(lstCopy)) # [['a', 'b'], 1, 2, 3] 2096824601928
print(id(lst[0])) # 2096824547592
print(id(lstCopy[0])) # 2096824546696
# 深拷贝后,改变任意一个对象中元素的值,只有当前对象受影响
lst[0][0] = 'aa'
lst[1] = 11
print(lst) # [['aa', 'b'], 11, 2, 3]
print(lstCopy) # [['a', 'b'], 1, 2, 3]
# 另外常使用的列表切片,也是浅拷贝,效果和copy.copy()相同
lstchild = ['a','b']
lst = [lstchild, 1, 2, 3]
lstCopy = lst[:]
print(lst,id(lst)) # [['a', 'b'], 1, 2, 3] 2096824546824
print(lstCopy,id(lstCopy)) # [['a', 'b'], 1, 2, 3] 2096824601928
print(id(lst[0])) # 2685187220808
print(id(lstCopy[0])) # 2685187220808
lst[0][0] = 'aa'
lst[1] = 11
print(lst) # [['aa', 'b'], 11, 2, 3]
print(lstCopy) # [['aa', 'b'], 1, 2, 3]
# 字典自带有copy()函数,这种拷贝为深拷贝
dict_ = {"a":1, "b":2}
dict_copy = dict.copy(dict_)
print(dict_, id(dict_)) # {'a': 1, 'b': 2} 1959416851840
print(dict_copy, id(dict_copy)) # {'a': 1, 'b': 2} 1959416851912
dict_["a"] = 11
dict_copy["b"] = 22
print(dict_) # {'a': 11, 'b': 2}
print(dict_copy) # {'a': 1, 'b': 22}