Python中,,對象的賦值,拷貝(深/淺拷貝)之間是有差異的,,如果使用的時候不注意,,就可能產(chǎn)生意外的結(jié)果,其實這個是由于共享內(nèi)存導致的結(jié)果,。 拷貝:原則上就是把數(shù)據(jù)分離出來,,復制其數(shù)據(jù),并以后修改互不影響,。 =賦值:數(shù)據(jù)完全共享(=賦值是在內(nèi)存中指向同一個對象,,如果是可變(mutable)類型,比如列表,,修改其中一個,,另一個必定改變是不可變類型(immutable),比如字符串,修改了其中一個,,另一個并不會變) l1=[1,2,3,['1','2','3']]l2=l1l2[0]='a'print(l1) # ['a', 2, 3, ['1', '2', '3']]l2[3][0]='b'print(l1) # ['a', 2, 3, ['b', '2', '3']]print(id(l1)==id(l2)) # True#總結(jié):l2 = l1 ,,l1 完全賦值給l2 ,l2的內(nèi)存地址與l1 相同,,即內(nèi)存完全指向# 傳遞對象的引用而已,原始列表改變,,被賦值的值也會做相同的改變 淺拷貝:數(shù)據(jù)半共享(復制其數(shù)據(jù)獨立內(nèi)存存放,但是只拷貝成功第一層) import copyl1 = [1, 2, 3, [11, 22, 33]]l2 = copy.copy(l1) # 淺拷貝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# 總結(jié):# 如上述代碼,,l2淺拷貝了l1 ,,之后l2把其列表中的列表的元素給修改,從結(jié)果看出,,l1也被修改了,。但是僅僅修改l1列表中的第一層元素,,卻并沒有影響l2。# 比較一下l2與l1的內(nèi)存地址:False,,說明,,l2在內(nèi)存中已經(jīng)獨立出一部分復制了l1的數(shù)據(jù),但是只是淺拷貝,,第二層的數(shù)據(jù)并沒有拷貝成功,,而是指向了l1中的第二層數(shù)據(jù)的內(nèi)存地址,所以共享內(nèi)存‘相當于‘’等號賦值’‘,,所以就會有l(wèi)2中第二層數(shù)據(jù)發(fā)生變化,l1中第二層數(shù)據(jù)也發(fā)生變化 深拷貝:數(shù)據(jù)完全不共享(復制其數(shù)據(jù)完完全全放獨立的一個內(nèi)存,,完全拷貝,,數(shù)據(jù)不共享) import copyl1 = [1, 2, 3, [11, 22, 33]]l2 = copy.deepcopy(l1) # 深拷貝print(l2) # [1,2,3,[11,22,33]]l2[3][2] = 'aaa'print(l1) # [1, 2, 3, [11, 22, 33]]print(l2) # [1, 2, 3, [11, 22, 'aaa']]l1[0] = 0print(l1) # [0, 2, 3, [11, 22, 33]]print(l2) # [1, 2, 3, [11, 22, 'aaa']]print(id(l1) == id(l2)) # Flase# 總結(jié):# 深拷貝就是完完全全復制了一份,且數(shù)據(jù)不會互相影響,,因為內(nèi)存不共享,。# 深拷貝就是數(shù)據(jù)完完全全獨立拷貝出來一份。不會由原先數(shù)據(jù)變動而變動 深淺拷貝的作用:1,,減少內(nèi)存的使用2,,以后在做數(shù)據(jù)的清洗、修改或者入庫的時候,,對原數(shù)據(jù)進行復制一份,,以防數(shù)據(jù)修改之后,找不到原數(shù)據(jù),。 |
|
來自: 昵稱11935121 > 《未命名》