標籤:logs 方式 效果 地址 概念 images 記憶體 簡單 問題
python在記憶體中儲存資料的結構
1先考慮一個問題為什麼python list是可以被追加的,也就是資料會不斷擴大?
當產生一個列表對象那麼python就會在記憶體中開闢一個地區來存放當前的值,如果在往裡追加def記憶體中的資料會是連續存放的嗎?
當然不會了,因為python就是利用c中的鏈表實現的追加方式,python建立列表的時候肯定不知道你需要儲存多少東西所以無法給你開闢很大的記憶體空間。
鏈表會記錄上一個位置和下一個位置,這樣就實現了追加的功能。
這裡在說一點,因為python是c來開發的,c中是沒有字串這個概念的, 只有字串數組。就向上面圖片一樣str="abc",abc就是分別存在三個記憶體塊上。
當python修改str="adc",此時會開闢三個新的記憶體塊來儲存
看下下面的例子:
這裡就是把list[0]的值改成xxx,從圖上可以看出,0的下標以前指向abc,改後0指向xxx了,但是abc實際上還在記憶體中並沒有消失。
淺拷貝
python對數字和字串有最佳化機制,這裡 無論深淺拷貝記憶體位址都是一樣的。
>>> n1=123
>>> n2=n1
>>> id(n1)
7367920L
>>> id(n2)
7367920L
>>> n1=123
>>> n2=copy.copy(n1)
>>> id(n1)
7367920L
>>> id(n2)
7367920L
>>> n2=copy.deepcopy(n1)
>>> id(n2)
7367920L
只要是數字或字串那麼不管如何cp都是指向同一個記憶體,實際上同樣的東西開闢2個記憶體空間就會很浪費,因為值都是一樣的。
如果把n1的值改成=456?那麼會影響n2的值嗎?當然不會了n2還是會指向123這個記憶體位址的。
那如果是資料類型是元組,列表,字典情況還是一樣的嗎?
先定義個資料類型
>>> n1={"k1":"abc","k2":123,"k3":["hello","999"]}
>>> n2=n1
淺拷貝的話n2隻會拷貝[k1,k2,k3]第一層記憶體id。
看看只拷貝第一層的效果:
2個id一樣沒有錯
>> id(n2[‘k1‘])
4109480L
>> id(n1[‘k1‘])
4109480L
這就有變化了,如果上直接cp一個字串,當A的值做出改變不會影響B,但是這裡B的值會隨著A的改變而改變。這就是只cp一層的問題。原因很簡單N2隻需要找k1就行,k1指標指向誰跟N2沒有關係
>> n1["k1"]="ccc"
>> id(n1[‘k1‘])
5415864L
>> id(n2[‘k1‘])
5415864L
>> n2["k1"]
ccc‘
>> n1["k1"]
ccc‘
python深淺拷貝