From pixabay
在python中有6种标准的数据类型,它们分别是可变的和不可变的,其中有3种是不可变的,它们分别是Number,String,Tuple;另外3种是可变的,它们分别是List,Dictionary,Set。类型不同,其深浅拷贝的的结果不同。
浅拷贝
浅拷贝用copy模块中的copy()方法实现,它有如下特点: (1)、对于不可变类型,浅拷贝仅仅是地址指向,不会开辟新的空间; (2)、对于可变类型,浅拷贝会开辟新的空间(仅仅是最顶层开辟空间,里层不会改变); (3)、浅拷贝后,如果改变原始数据中可变类型的值,拷贝后对象的值也会受影响,如果改变原始数据中不可变类型的值,只有原始数据受影响,拷贝后对象的值不受影响; 例如对于不可变类型:
# Number
>>> num1 = 66
>>> num2 = copy.copy(num1)
>>> print("num1:{}".format(id(num1)))
num1:140718733224624
>>> print("num2:{}".format(id(num2)))
num2:140718733224624
# String
>>> str1 = "hello"
>>> str2 = copy.copy(str1)
>>> print("str1:{}".format(id(str1)))
str1:2953634367896
>>> print("str2:{}".format(id(str2)))
str2:2953634367896
# Tuple
>>> tup1 = (1,2)
>>> tup2 = copy.copy(tup1)
>>> print("tup1:{}".format(id(tup1)))
tup1:2953634226824
>>> print("tup2:{}".format(id(tup2)))
tup2:2953634226824
>>>
# 分别修改原始数据
>>> num1 = 77
>>> num2
66
>>> str1 = "world"
>>> str2
'hello'
>>> tup1 = (3,4)
>>> tup2
(1, 2)
>>>
对于可变数据类型,例如:
# List
>>> list1 = [1,2,3]
>>> list2 = copy.copy(list1)
>>> print("list1:{}".format(id(list1)))
list1:2953634215688
>>> print("list2:{}".format(id(list2)))
list2:2953634365192
>>> list11 = [4,5,[6,7,8]]
>>> list12 = copy.copy(list11)
>>> print("list11:{}".format(id(list11)))
list11:2953634365064
>>> print("list12:{}".format(id(list12)))
list12:2953634365320
# Dictionary
>>> dict1 = {"name": "joker", "age": 18}
>>> dict2 = copy.copy(dict1)
>>> print("dict1:{}".format(id(dict1)))
dict1:2953634147640
>>> print("dict2:{}".format(id(dict2)))
dict2:2953634194272
# Set
>>> set1 = {'a','b'}
>>> set2 = copy.copy(set1)
>>> print("set1:{}".format(id(set1)))
set1:2953634207336
>>> print("set2:{}".format(id(set2)))
set2:2953634208232
# 对原始数据进行修改
>>> list1[0]=100
>>> list2
[1, 2, 3]
>>> dict1["age"]=33
>>> dict2
{'name': 'joker', 'age': 18}
>>> list11[0]=400
>>> list12
[4, 5, [6, 7, 8]]
>>> list11[2][1]=600
>>> list12
[4, 5, [6, 600, 8]]
>>>
如果原始数据是可变类型,如下:
>>> list3 = [100,200,300]
>>> list4 = [500,600,700]
>>> num = 999
>>> list34 = [list3, list4, num]
>>> list56 = copy.copy(list34)
>>> num = 888
>>> list34
[[100, 200, 300], [500, 600, 700], 999]
>>> list56
[[100, 200, 300], [500, 600, 700], 999]
>>> list3[0]=1000
>>> list34
[[1000, 200, 300], [500, 600, 700], 999]
>>> list56
[[1000, 200, 300], [500, 600, 700], 999]
>>>
深拷贝
深拷贝用copy模块中deepcopy()方法实现,它有如下特点: (1)、深拷贝就是克隆了一份,完全复制; (2)、经过深拷贝后,原始对象和新拷贝的对象是相互独立的;
对于只有一层的数据,深拷贝和浅拷贝几乎一致,因为深拷贝更多的是强调递归,强调的是资源数,如下:
>>> list3 = [100,200,300]
>>> list4 = [500,600,700]
>>> num = 999
>>> list34 = [list3, list4, num]
>>> list78 = copy.deepcopy(list34)
>>> num = 888
>>> list34
[[100, 200, 300], [500, 600, 700], 999]
>>> list78
[[100, 200, 300], [500, 600, 700], 999]
>>> list3[0]=1000
>>> list34
[[1000, 200, 300], [500, 600, 700], 999]
>>> list78
[[100, 200, 300], [500, 600, 700], 999]
>>>
本例是跟浅拷贝做对比的。 在之前的浅拷贝中,子元素是不会开辟新空间做拷贝的。 而在深拷贝中,子元素也进行了拷贝。