標籤:sans 不可 back pos ima pytho 注意 共用 ica
拷貝就是拷貝,何來深淺之說?
Python中,對象的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時候不注意,就可能產生意外的結果
其實這個是由於共用記憶體導致的結果
拷貝:原則上就是把資料分離出來,複製其資料,並以後修改互不影響。
先看 一個非拷貝的例子
=賦值:資料完全共用(=賦值是在記憶體中指向同一個對象,如果是可變(mutable)類型,比如列表,修改其中一個,另一個必定改變
如果是不可變類型(immutable),比如字串,修改了其中一個,另一個並不會變
)
l1 = [1, 2, 3, [‘aa‘, ‘bb‘]]l2 = l1l2[0]=‘aaa‘l2[3][0]=‘bbb‘print(l1) #[‘aaa‘, 2, 3, [‘bbb‘, ‘bb‘]]print(id(l1)==id(l2)) #True
l2 = l1 ,l1 完全賦值給l2 ,l2的記憶體位址與l1 相同,即記憶體完全指向
淺拷貝:資料半共用(複製其資料獨立記憶體存放,但是只拷貝成功第一層)
1,完全切片方法;2,工廠函數,如list();3,copy模組的copy()函數
l1 = [1,2,3,[11,22,33]]l2 = l1.copy()print(l2) #[1,2,3,[11,22,33]]l2[3][2]=‘aaa‘print(l1) #[1, 2, 3, [11, 22, ‘aaa‘]]print(l2) #[1, 2, 3, [11, 22, ‘aaa‘]]l1[0]= 0print(l1) #[0, 2, 3, [11, 22, ‘aaa‘]]print(l2) #[1, 2, 3, [11, 22, ‘aaa‘]]print(id(l1)==id(l2)) #Flase
如上述代碼,l2淺拷貝了l1 ,之後l2把其列表中的列表的元素給修改,從結果看出,l1也被修改了。但是僅僅修改l1列表中的第一層元素,卻並沒有影響l2。
比較一下l2與l1的記憶體位址:False,說明,l2在記憶體中已經獨立出一部分複製了l1的資料,但是只是淺拷貝,第二層的資料並沒有拷貝成功,而是指向了l1中的第二層資料的記憶體位址,所以共用記憶體‘相當於‘’等號賦值’‘,所以就會有l2中第二層資料發生變化,l1中第二層資料也發生變化
,這就是淺拷貝的原理,l2拷貝l1的時候只拷貝了他的第一層,也就是在其他記憶體中重新建立了l1的第一層資料,但是l2無法拷貝l1的第二層資料,也就是列表中的列表,所以他就只能指向l1中的第二層資料
由此,當修改l1中第二層資料的時候,淺拷貝l1的l2中的第二層資料也隨之發生改變
深拷貝:資料完全不共用(複製其資料完完全全放獨立的一個記憶體,完全拷貝,資料不共用)
深拷貝就是完完全全複製了一份,且資料不會互相影響,因為記憶體不共用。
深拷貝的方法有
匯入模組
import copyl1 = [1, 2, 3, [11, 22, 33]]# l2 = copy.copy(l1) 淺拷貝l2 = copy.deepcopy(l1)print(l1,‘>>>‘,l2)l2[3][0] = 1111print(l1,">>>",l2)
由此可見深拷貝就是資料完完全全獨立拷貝出來一份。不會由原先資料變動而變動
Python之深淺拷貝