python 直接賦值 深拷貝 淺拷貝
阿新 • • 發佈:2022-03-08
目錄
python中的深拷貝與淺拷貝與C&C++中略有不同,後者主要是對於指標指向記憶體空間的重新開闢,否則兩個指標會共享一塊記憶體,而python中是三種不同層次的共享。其中直接複製是用 = ,淺拷貝和深拷貝則要使用copy模組實現。
python中的深拷貝與淺拷貝與C&C++中略有不同,後者主要是對於指標指向記憶體空間的重新開闢,否則兩個指標會共享一塊記憶體,而python中是三種不同層次的共享。其中直接複製是用 = ,淺拷貝和深拷貝則要使用copy模組實現。
直接賦值
d = {'country':'China', 'age': '18', 'name': 'Kang'}
a = d
print(a, d)
d['age'] = 100
print(a, d)
d['like'] = 'pingpong'
print(a, d)
輸出:
{'country': 'China', 'age': '18', 'name': 'Kang'} {'country': 'China', 'age': '18', 'name': 'Kang'} {'country': 'China', 'age': 100, 'name': 'Kang'} {'country': 'China', 'age': 100, 'name': 'Kang'} {'country': 'China', 'age': 100, 'name': 'Kang', 'like': 'pingpong'} {'country': 'China', 'age': 100, 'name': 'Kang', 'like': 'pingpong'}
直接賦值的時候 a與d完全相同,類似C中的引用概念,是一個物件的兩個別名,因此無論是改變d中原有元素還是給d新增新的元素,a都是隨之改變。
淺拷貝
直接賦值是兩個物件完全共享,淺拷貝則是共享拷貝時候已有的元素,對於新增的新元素則不共享。
import copy
d = {'country':'China', 'age': '18', 'name': 'Kang'}
a = copy.copy(d)
print(a, d)
d['age'] = 100
print(a, d)
d['like'] = 'pingpong'
print(a, d)
輸出:
{'country': 'China', 'age': '18', 'name': 'Kang'} {'country': 'China', 'age': '18', 'name': 'Kang'} {'country': 'China', 'age': '18', 'name': 'Kang'} {'country': 'China', 'age': 100, 'name': 'Kang'} {'country': 'China', 'age': '18', 'name': 'Kang'} {'country': 'China', 'age': 100, 'name': 'Kang', 'like': 'pingpong'}
嗯,第三行是對的,對於新新增的元素不會共享。但本來以為改變原字典d的age的值,a會跟著改變的,畢竟age是共享時已有的元素嘛,但這裡發現好像打臉了,第二行輸出d的age改變而a沒有改變,這是因為字典的值更改了以後就相當於一個新的元素了。以下小實驗可驗證:
d = {'age': 18}
print(id(d['age']))
d['age'] = 10000
print(id(d['age']))
輸出為:
93899669444160
139985819449552
可以認為id()函式輸出物件的地址,可以看到這裡地址已經改變了,所以d的age鍵值對改變前後是兩個元素。
即,淺拷貝時子元素共享是對的,但是要注意改變子元素時有沒有改變其地址,把原本共享的子元素物件直接改成另一個物件,那肯定不再共享了。
深拷貝
a = copy.deepcopy(d)
這種情況下a和d完全不相關,不存在任何共享。