提到拷贝,主要使用赋值、copy模块、列表切片、字典copy() 来实现拷贝。
赋值
赋值产生的拷贝是浅拷贝,共享地址。
改变任意一个对象中元素的值,会同时影响拷贝对象,当前对象怎么变,拷贝的对象就跟着怎么变。
1 2 3 4 5 6 7 8 9 10 11
| list1 = [1,2,3,4,5] list2 = list1 list2[0] = 100 print(list1,id(list1)) print(list2,id(list2))
list1 = [[1,2,3],2,3,4,5] list2 = list1 list2[0][0] = 100 print(list1,id(list1)) print(list2,id(list2))
|
Copy
浅拷贝 copy.copy()
对于不可变类型:数字、字符串、元组, 浅拷贝仅仅是地址,即就是使用相同的地址,引用相同的地址id,不会开辟新空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import copy
iNum = 1 iNewNum = copy.copy(iNum) print(iNum,id(iNum)) print(iNewNum,id(iNewNum))
lstchild = ['a','b'] lst = [lstchild, 1, 2, 3] lstCopy = copy.copy(lst) print(lst,id(lst)) print(lstCopy,id(lstCopy)) print(id(lst[0])) print(id(lstCopy[0]))
|
1 2 3 4 5 6 7 8 9 10 11 12
|
lst[0][0] = 'aa' lst[1] = 11 print(lst) print(lstCopy)
lst[0] = "ab" print(lst) print(lstCopy)
|
深拷贝 copy.deepcopy()
copy.deepcopy() 除了外层拷贝,还对子元素也进行了拷贝(本质上递归浅拷贝)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import copy lstchild = ['a','b'] lst = [lstchild, 1, 2, 3] lstCopy = copy.deepcopy(lst) print(lst,id(lst)) print(lstCopy,id(lstCopy)) print(id(lst[0])) print(id(lstCopy[0]))
lst[0][0] = 'aa' lst[1] = 11 print(lst) print(lstCopy)
|
列表切片
常使用的列表切片,也是浅拷贝,效果和 copy.copy() 相同
1 2 3 4 5 6 7 8 9 10 11 12
| lstchild = ['a','b'] lst = [lstchild, 1, 2, 3] lstCopy = lst[:] print(lst,id(lst)) print(lstCopy,id(lstCopy)) print(id(lst[0])) print(id(lstCopy[0]))
lst[0][0] = 'aa' lst[1] = 11 print(lst) print(lstCopy)
|
字典拷贝
字典自带有 copy() 函数,这种拷贝为浅拷贝
1 2 3 4 5 6 7 8 9 10 11 12
| original_dict = {'a': 1, 'b': [2, 3], 'c': {'d': 4}} copied_dict = original_dict.copy()
original_dict['a'] = 10
original_dict['b'].append(4) original_dict['c']['d'] = 5
print(original_dict) print(copied_dict)
|
要想深拷贝,还得用 copy.deepcopy()
1 2 3 4 5 6 7 8 9 10
| import copy
original_dict = {'a': 1, 'b': [2, 3], 'c': {'d': 4}} deep_copied_dict = copy.deepcopy(original_dict)
original_dict['b'].append(4) original_dict['c']['d'] = 5 print(original_dict) print(deep_copied_dict)
|