天天看點

Python中的資料存儲以及拷貝詳解

作者:劉聰明LCM

引言:

在本人逛頭條的過程中,經常看到有創作者出形如下圖的題目考各位條友,似乎該類題目天生自帶流量,今天我将就我所知道的相關内容淺談一二。

Python中的資料存儲以及拷貝詳解

輸出結果應為:[12306,119,120]

一、Python中的資料對象怎麼存儲

1.數組的資料存儲

在其他進階語言當中,有一類叫數組的資料結構,在建立數組對象時,一般都要事先聲明所創對象的資料類型和大小,這兩個屬性一旦确定,後續能存入這個數組對象的元素就被限定。

Python中的資料存儲以及拷貝詳解

示例

如示例數組a,假設它是一個整數數組,每個元素占4個位元組,數組從記憶體首位址10開始順序存放元素,那麼資料存放情況就應該大緻如圖所示,在知道首位址和每個元素所占記憶體的情況下,我們要通路其中的資料,比如120,就可以直接查找開始記憶體為10+4*2的這個元素,這也是數組通路元素的方法。(對于這部分的知識點我不太清楚,如有錯誤還望指正!)

2.Python清單的資料存儲

而在Pythom當中,建立資料對象不用聲明對象的類型和大小,Python中的清單與數組非常相似,但有兩個明顯差別,1.清單對象可以随意擴充;2.清單對象中的元素類型可以不相同。

對于a = [[1,2,3],3.14,'python']這樣的一個指派語句,實際的資料存儲情況可能如下圖。

Python中的資料存儲以及拷貝詳解

示例

變量a通過id記憶體位址指向最外層的清單,而記憶體的清單、浮點數、字元串又通過各自的id指向相應的元素,通路元素的時候一層層通過id進行查找,由于id大小都是一樣的,是以元素的類型就可以不相同。

二、相等和相同

我們在判斷兩個對象是否相等時,一般會用到==比較運算符,這個其實比較的是兩個對象的值是否一樣,隻要值是一樣的,傳回的結果就是True,而判斷兩個對象是否相同(為同一個對象)則需要用到is身份運算符,隻有當兩個對象的id也就是記憶體位址一樣時,傳回的結果才是True,顯然,相同的對象肯定相等,但相等的對象不一定相同。

我們可以用id()函數檢視對象的記憶體位址。

Python中的資料存儲以及拷貝詳解

id函數的解釋

Python中的資料存儲以及拷貝詳解

示例

三、指派語句

指派語句包括等于(=)、加等于(+=)、減等于(-=)等等,将一個對象指派給一個變量是指建立一個引用,将變量指向對象。

在文章開頭的那個問題當中,我們先建立一個變量a指向一個清單對象,然後又将變量a指派給變量b,其實就相當于建立了一個新的變量b,它和變量a具有相同的引用,都指向[110,119,120]這個清單對象,是以在通過變量b修改這個清單對象後,通過變量a通路這個清單對象時會顯示為修改後的樣子,因為自始至終記憶體中都隻有一個清單對象。

四、兩個機制

1.小整數池對象機制

Python解釋器為了節約記憶體、提高效率,會将我們常用的小整數裝入對象池,這些小整數在Python解釋器中會提前建立好,所有位于這個範圍内的數都将使用同一個對象,對于單個字母也是這樣的機制,小整數池的範圍是[-5,256]。

Python中的資料存儲以及拷貝詳解

示例

2.字元串駐存機制

字元串隻包含大小寫字母、數字、下劃線時,采用駐存機制,即記憶體中隻存儲一個相同的字元串對像。

Python中的資料存儲以及拷貝詳解

示例

五、淺拷貝

淺拷貝通俗的講指僅在第一個次元建立了新副本,在第一個次元修改其中一個變量時,另一個變量不會改變。

淺拷貝的常見方式:

1.資料構造方法

Python中的資料存儲以及拷貝詳解

示例

2.切片

Python中的資料存儲以及拷貝詳解

示例

3.copy()函數

Python中的資料存儲以及拷貝詳解

示例

但是,淺拷貝在更深的次元修改一個變量時,另一個變量也會跟着改變,這就是叫淺拷貝的原因。

Python中的資料存儲以及拷貝詳解

示例

從示例中我們可以看到,變量b是變量a的淺拷貝,我們在第一個次元修改變量a時,變量b沒有跟着改變,而在第二個次元修改變量a時,變量b卻跟着改變了。

這是因為變量a和變量b中的内嵌清單還是具有相同的引用。

Python中的資料存儲以及拷貝詳解

示例

六、深拷貝

深拷貝相對于淺拷貝而言,則是完全建立了一個新的副本,新舊變量是兩個完全不同的對象,是以不管怎麼改變其中一個變量,另一個變量都不會改變。

Python中的資料存儲以及拷貝詳解

示例