1、赋值操作
python在赋值操作时 如果是可变数据类型修改了其中一个变量,另一个跟着改变。注意对不可变对象,新赋值,就是修改了指向。(int、字符串(string)、float、(数值型number)、元组(tuple))
s1 = 'ab' s2 = s1 print(s1, s2) # ab ab print(id(s1), id(s2)) # 1888495190848 1888495190848 s2 = 'cd' print(s1, s2) # ab cd print(id(s1), id(s2)) # 1888495190848 1888495191016 l1 = [1, 3, [5, ]] l2 = l1 print(l1, l2) # [1, 3, [5]] [1, 3, [5]] print(id(l1), id(l2)) # 2228045300040 2228045300040 l2.append(2) l1[2].append(6) print(id(l1[1]), id(l2[1])) # 1679715136 1679715136 print(l1, l2) # [1, 3, [5, 6], 2] [1, 3, [5, 6], 2]
2、浅拷贝
浅拷贝相当于重新开辟了一块对象空间,但是空间中的可变和不可变元素的地址都相同。注意 对于可变类型中的可变类型的修改是会互相影响的。
l1 = [1, 3, [5, ]] l2 = l1.copy() print(l1, l2) # [1, 3, [5]] [1, 3, [5]] print(id(l1), id(l2)) # 1786145751368 1786145752008 l1.append(2) l1[2].append(6) print(id(l1[1]), id(l2[1])) # 1679715136 1679715136 print(l1, l2) # [1, 3, [5, 6], 2] [1, 3, [5, 6]]
3、深拷贝 相当于重新开辟了一块对象空间,但是空间中的可变的地址相同(可变元素指向相同),不可变元素的地址不同(不可变元素重新开辟空间)。
from copy import deepcopy l1 = [1, 3, [5, ]] l2 = deepcopy(l1) print(l1, l2) # [1, 3, [5]] [1, 3, [5]] print(id(l1), id(l2)) # 2995101844168 2995101849736 l1.append(2) l1[2].append(6) print(id(l1[1]), id(l2[1])) # 1679715136 1679715136 print(id(l1[2]), id(l2[2])) # 2177305756616 2177305760904 print(l1, l2) # [1, 3, [5, 6], 2] [1, 3, [5]]
总结:
-
赋值是将一个对象的地址赋值给一个变量,让变量指向该地址( 旧瓶装旧酒 )。
-
浅拷贝是在另一块地址中创建一个新的变量或容器,但是容器内的元素的地址均是源对象的元素的地址的拷贝。也就是说新的容器中指向了旧的元素( 新瓶装旧酒 )。
-
深拷贝是在另一块地址中创建一个新的变量或容器,同时容器内的元素的地址也是新开辟的,仅仅是值相同而已,是完全的副本。也就是说( 新瓶装新酒 )。