引言:
在本人逛頭條的過程中,經常看到有創作者出形如下圖的題目考各位條友,似乎該類題目天生自帶流量,今天我将就我所知道的相關内容淺談一二。
輸出結果應為:[12306,119,120]
一、Python中的資料對象怎麼存儲
1.數組的資料存儲
在其他進階語言當中,有一類叫數組的資料結構,在建立數組對象時,一般都要事先聲明所創對象的資料類型和大小,這兩個屬性一旦确定,後續能存入這個數組對象的元素就被限定。
示例
如示例數組a,假設它是一個整數數組,每個元素占4個位元組,數組從記憶體首位址10開始順序存放元素,那麼資料存放情況就應該大緻如圖所示,在知道首位址和每個元素所占記憶體的情況下,我們要通路其中的資料,比如120,就可以直接查找開始記憶體為10+4*2的這個元素,這也是數組通路元素的方法。(對于這部分的知識點我不太清楚,如有錯誤還望指正!)
2.Python清單的資料存儲
而在Pythom當中,建立資料對象不用聲明對象的類型和大小,Python中的清單與數組非常相似,但有兩個明顯差別,1.清單對象可以随意擴充;2.清單對象中的元素類型可以不相同。
對于a = [[1,2,3],3.14,'python']這樣的一個指派語句,實際的資料存儲情況可能如下圖。
示例
變量a通過id記憶體位址指向最外層的清單,而記憶體的清單、浮點數、字元串又通過各自的id指向相應的元素,通路元素的時候一層層通過id進行查找,由于id大小都是一樣的,是以元素的類型就可以不相同。
二、相等和相同
我們在判斷兩個對象是否相等時,一般會用到==比較運算符,這個其實比較的是兩個對象的值是否一樣,隻要值是一樣的,傳回的結果就是True,而判斷兩個對象是否相同(為同一個對象)則需要用到is身份運算符,隻有當兩個對象的id也就是記憶體位址一樣時,傳回的結果才是True,顯然,相同的對象肯定相等,但相等的對象不一定相同。
我們可以用id()函數檢視對象的記憶體位址。
id函數的解釋
示例
三、指派語句
指派語句包括等于(=)、加等于(+=)、減等于(-=)等等,将一個對象指派給一個變量是指建立一個引用,将變量指向對象。
在文章開頭的那個問題當中,我們先建立一個變量a指向一個清單對象,然後又将變量a指派給變量b,其實就相當于建立了一個新的變量b,它和變量a具有相同的引用,都指向[110,119,120]這個清單對象,是以在通過變量b修改這個清單對象後,通過變量a通路這個清單對象時會顯示為修改後的樣子,因為自始至終記憶體中都隻有一個清單對象。
四、兩個機制
1.小整數池對象機制
Python解釋器為了節約記憶體、提高效率,會将我們常用的小整數裝入對象池,這些小整數在Python解釋器中會提前建立好,所有位于這個範圍内的數都将使用同一個對象,對于單個字母也是這樣的機制,小整數池的範圍是[-5,256]。
示例
2.字元串駐存機制
字元串隻包含大小寫字母、數字、下劃線時,采用駐存機制,即記憶體中隻存儲一個相同的字元串對像。
示例
五、淺拷貝
淺拷貝通俗的講指僅在第一個次元建立了新副本,在第一個次元修改其中一個變量時,另一個變量不會改變。
淺拷貝的常見方式:
1.資料構造方法
示例
2.切片
示例
3.copy()函數
示例
但是,淺拷貝在更深的次元修改一個變量時,另一個變量也會跟着改變,這就是叫淺拷貝的原因。
示例
從示例中我們可以看到,變量b是變量a的淺拷貝,我們在第一個次元修改變量a時,變量b沒有跟着改變,而在第二個次元修改變量a時,變量b卻跟着改變了。
這是因為變量a和變量b中的内嵌清單還是具有相同的引用。
示例
六、深拷貝
深拷貝相對于淺拷貝而言,則是完全建立了一個新的副本,新舊變量是兩個完全不同的對象,是以不管怎麼改變其中一個變量,另一個變量都不會改變。
示例