python中資料型別的底層實現

2021-10-07 12:50:59 字數 1500 閱讀 5013

通過緊湊陣列 實現字串的儲存, 字串資料在記憶體中是連續存放的,空間利用率高

原因是:每個字元的大小是固定的,因此乙個字串的大小也是固定的,可以分配乙個固定大小的空間給字串。

同為序列型別,為什麼列表採用引用陣列,而字串採用緊湊資料

雖然同為序列型別,但列表可以儲存的元素型別是多種多樣的,並且列表是可變的,無法預估記憶體空間,所以列表不能通過緊湊陣列。

python中的列表是由對其它物件的引用組成的連續陣列。指向這個陣列的指標及其長度被儲存在乙個列表頭結構中。這意味著,每次新增或刪除乙個元素時,由引用組成的陣列需要該標大小(重新分配)。幸運的是,python在建立這些陣列時採用了指數過分配,所以並不是每次操作都需要改變陣列的大小。但是,也因為這個原因新增或取出元素的平攤複雜度較低。

不幸的是,在普通鍊錶上「代價很小」的其它一些操作在python中計算複雜度相對過高。

利用 list.insert方法在任意位置插入乙個元素——複雜度o(n)

本質是順序表,只不過每次表的擴容都是指數級,所以動態增刪資料時,表並不會頻繁改變物理結構,同時受益於順序表遍歷的高效性(通過角標配合表頭實體地址,計算目標元素的位置),使得python的list綜合性能比較優秀;

python中所有不可變的內建型別都是可雜湊的。可變型別(如列表,字典和集合)就是不可雜湊的,因此不能作為字典的鍵。

字典的三個基本操作(新增元素,獲取元素和刪除元素)的平均事件複雜度為o(1),但是他們的平攤最壞情況複雜度要高得多,為o(n)

還有一點很重要,在複製和遍歷字典的操作中,最壞的複雜度中的n是字典曾經達到的最大元素數目,而不是當前的元素數目。換句話說,如果乙個字典曾經元素個數很多,後來又大大減小了,那麼遍歷這個字典可能會花費相當長的事件。因此在某些情況下,如果需要頻繁的遍歷某個詞典,那麼最好建立乙個新的字典物件,而不是僅在舊字典中刪除元素。

字典的底層實現 : python 字典的底層實現是雜湊表。呼叫內部的雜湊函式,將鍵(key)作為引數進行轉換(雜湊運算+取餘運算),得到乙個唯一的位址(位址的索引),然後將值(value)存放到對應位址中(給相同的鍵賦值會直接覆蓋原值,因為相同的鍵轉換後的位址是一樣的)。

本質上是順序表,不過每個元素儲存位置的角標,不是又插入順序決定的,而是由key經過hash演算法和其他機制,動態生成的,即key通過hash雜湊,生成value應該儲存的位置,然後再去儲存這個value;所以dict的查詢時間複雜度是o(1);因此,dict的key只能為可hash的物件,即不可變型別;

set(): 一種可變的、無序的、有限的集合,其元素是唯一的、不可變的(可雜湊的)物件。

cpython中集合和字典非常相似。事實上,集合被實現為帶有空值的字典,只有鍵才是實際的集合元素。此外,集合還利用這種沒有值的對映做了其它的優化。

由於這一點,可以快速的向集合中新增元素、刪除元素、檢查元素是否存在。平均時間複雜度為o(1),最壞的事件複雜度是o(n)。

set集合和dict一樣也是基於雜湊表的,只是他的表元只包含值的引用而沒有對鍵的引用,其他的和dict基本上是一致的。

tuple 本質上就是順序表,不可修改不可擴容,唯讀;

python的幾種常見資料型別底層細節實現

通過緊湊陣列 實現字串的儲存,字串資料在記憶體中是連續存放的,空間利用率高 原因是 每個字元的大小是固定的,因此乙個字串的大小也是固定的,可以分配乙個固定大小的空間給字串。同為序列型別,為什麼列表採用引用陣列,而字串採用緊湊資料 雖然同為序列型別,但列表可以儲存的元素型別是多種多樣的,並且列表是可變...

Redis Redis資料型別底層結構

參考 redis設計與實現 redis伺服器的16個庫由redisserver結構體來儲存 struct redisserverredis客戶端,通過修改指向的redis伺服器的db指標,來切換資料庫 redis中的乙個庫下所有k v全都儲存在乙個字典內部 乙個庫乙個鍵空間 redis五種資料結構底...

Python中的資料型別

python中有五種標準的資料型別 數字 字串 列表 元組 字典1 數字型別 number 數字資料型別儲存數字值,當為其分配值時,將建立數字物件。例如 var1 10 var2 20可以使用del語句刪除對數字物件的引用。其語法為 del var del var1,var2python支援三種不同...