copy,拷貝,顧名思義,自然是把東西復制過來,呈現在眼前的是一樣的,例如:
a = [1,2,3,4,5] b = a b.append(6) print(a,b)
輸出:
[1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
很明顯,a和b的值是一樣的。因為對於賦值運算來講,a與b指向的是同一內存地址,所以他們完全是一樣的
淺copy:
a = [1,2,3,4,[5]] b = copy.copy(a) b[4].append(6) print(a) print(b) print(id(a)) print(id(b)) print(id(a[0])) print(id(b[0])) print(id(a[4])) print(id(b[4]))
輸出:
[1, 2, 3, 4, [5, 6]] [1, 2, 3, 4, [5, 6]] 3123924048968 3123924049032 140709039403264 140709039403264 3123924285128 3123924285128
可以看到,a和b的輸出地址不一樣,原因是對於淺copy來說,只是在內存中重新創建了開辟了一個空間存放一個新列表,但是新列表中的元素與原列表中的元素是公用的,且元素原地址一樣不變。
但我們如果對它進行增刪改,兩者是否會相互改變呢?
從上面看,列表當中的可變數據類型進行增加元素時,兩者是會相互影響的,且地址一直一致;
但從下面看,對列表當中的不可變數據類型進行修改時,雖然元素地址一樣,但兩者是不會相互影響,並且經過修改后,元素地址發生改變,兩者地址變得不一樣。
import copy a = [1,2,3,4,[5]] b = copy.copy(a) b[0] = 0
print(a)
print(b)
print(id(a[0])) print(id(b[0]))
輸出:
[1, 2, 3, 4, [5]] [0, 2, 3, 4, [5]] 140709362168064 140709362168032
而在整個列表添加新的元素時,兩者同樣不會相互影響,只要copy過來的元素不發生改變,元素地址會一直保持一致
import copy a = [1,2,3,4,[5]] b = copy.copy(a) b.append(8) print(a) print(b) print(id(a[0])) print(id(b[0]))
輸出:
[1, 2, 3, 4, [5]] [1, 2, 3, 4, [5], 8] 140709362168064 140709362168064
所以得出結論是,淺copy時,內存會開辟一個新的空間存放一個新的列表,所以地址不一致。列表中的元素和元素地址都會被copy過來,而可變數據類型(列表中的列表,二級列表)被當作一個整體不被拷貝,所以地址永遠一致,對可變數據類型中的元素改變時,a和b會相互影響,元素永遠相同。
而一級列表中的不可變數據類型,雖然元素與地址都被復制過來,但兩者進行修改時不會相互影響,並且修改后地址會變得不一致。而在一級列表添加新的元素時,兩者同樣不會相互影響,只要不改變copy過來的元素,地址會一直與copy過來的一致。
深copy:
import copy a = [1,2,3,4,[5]] b = copy.deepcopy(a) b[4].append(6) print(a) print(b) print(id(a)) print(id(b)) print(id(a[0])) print(id(b[0])) print(id(a[4])) print(id(b[4]))
輸出:
[1, 2, 3, 4, [5]] [1, 2, 3, 4, [5, 6]] 1861657304264 1861657304328 140709043532032 140709043532032 1861657540168 1861657304456
它是拷貝所有內容。包括內部(列表的列表)的所有,形成一個新的對象,雖然與之前的值和內容一模一樣,但是它們時完完全全的兩個對象,所以不僅a和b的地址不同,可變數據類型的地址同樣被拿出來存在新的內存當中,地址同樣會不一樣,所以做出改變時不會相互影響;其它與淺copy一致,不可變數據類型改變時不會相互影響,且改變后地址會發生改變;
注:
當切片進行賦值時,兩者地址會不一樣,並且進行增刪改時,兩者互不影響:
a = [1,2,3,4,5] b = a[0::] b.pop(0) print(a) print(b) print(id(a)) print(id(b))
輸出:
[1, 2, 3, 4, 5] [2, 3, 4, 5] 2525473650376 2525473414152
僅存在一種情況,兩者相互影響且地址永遠一致:
a = [1,2,3,4,5] b = a b.append(6) a.pop(2) print(a) print(b) print(id(a)) print(id(b))
輸出:
[1, 2, 4, 5, 6] [1, 2, 4, 5, 6] 2957431125704 2957431125704
以上測試基於python3.7.4