字典型別是python中最常用的資料型別之一,它是乙個鍵值對的集合,字典通過鍵來索引,關聯到相對的值,理論上它的查詢複雜度是 o(1) :
>>> d =
>>> d['c'] = 3
>>> d
在字串的實現原理文章中,曾經出現過字典物件用於intern操作,那麼字典的內部結構是怎樣的呢?pydictobject物件就是dict的內部實現。
雜湊表 (hash tables)
雜湊表(也叫雜湊表),根據關鍵值對(key-value)而直接進行訪問的資料結構。它通過把key和value對映到表中乙個位置來訪問記錄,這種查詢速度非常快,更新也快。而這個對映函式叫做雜湊函式,存放值的陣列叫做雜湊表。 雜湊函式的實現方式決定了雜湊表的搜尋效率。具體操作過程是:
資料新增:把key通過雜湊函式轉換成乙個整型數字,然後就將該數字對陣列長度進行取餘,取餘結果就當作陣列的下標,將value儲存在以該數字為下標的陣列空間裡。
資料查詢:再次使用雜湊函式將key轉換為對應的陣列下標,並定位到陣列的位置獲取value。
但是,對key進行hash的時候,不同的key可能hash出來的結果是一樣的,尤其是資料量增多的時候,這個問題叫做雜湊衝突。如果解決這種衝突情況呢?通常的做法有兩種,一種是鏈結法,另一種是開放定址法,python選擇後者。
開放定址法(open addressing)
開放定址法中,所有的元素都存放在雜湊表裡,當產生雜湊衝突時,通過乙個探測函式計算出下乙個候選位置,如果下乙個獲選位置還是有衝突,那麼不斷通過探測函式往下找,直到找個乙個空槽來存放待插入元素。
pydictentry
字典中的乙個key-value鍵值對元素稱為entry(也叫做slots),對應到python內部是pydictentry,pydictobject就是pydictentry的集合。pydictentry的定義是:
typedef struct pydictentry;
me_hash用於快取me_key的雜湊值,防止每次查詢時都要計算雜湊值,entry有三種狀態。
unused: me_key == me_value == null
unused是entry的初始狀態,key和value都為null。插入元素時,unused狀態轉換成active狀態。這是me_key為null的唯一情況。
active: me_key != null and me_key != dummy 且 me_value != null
插入元素後,entry就成了active狀態,這是me_value唯一不為null的情況,刪除元素時active狀態刻轉換成dummy狀態。
dummy: me_key == dummy 且 me_value == null
此處的dummy物件實際上乙個pystringobject物件,僅作為指示標誌。dummy狀態的元素可以在插入元素的時候將它變成active狀態,但它不可能再變成unused狀態。
為什麼entry有dummy狀態呢?這是因為採用開放定址法中,遇到雜湊衝突時會找到下乙個合適的位置,例如某元素經過雜湊計算應該插入到a處,但是此時a處有元素的,通過探測函式計算得到下乙個位置b,仍然有元素,直到找到位置c為止,此時abc構成了探測鏈,查詢元素時如果hash值相同,那麼也是順著這條探測鏈不斷往後找,當刪除探測鏈中的某個元素時,比如b,如果直接把b從雜湊表中移除,即變成unused狀態,那麼c就不可能再找到了,因為ac之間出現了斷裂的現象,正是如此才出現了第三種狀態---dummy,dummy是一種類似的偽刪除方式,保證探測鏈的連續性。
pydictobject
影音先鋒電影
pydictobject使用pyobject_head而不是pyobject_var_head,雖然字典也是變長物件,但此處並不是通過ob_size來儲存字典中元素的長度,而是通過ma_used欄位。
Python字典物件實現原理
字典型別是python中最常用的資料型別之一,它是乙個鍵值對的集合,字典通過鍵來索引,關聯到相對的值,理論上它的查詢複雜度是 o 1 d d c 3 d 在字串的實現原理文章中,曾經出現過字典物件用於intern操作,那麼字典的內部結構是怎樣的呢?pydictobject物件就是dict的內部實現。...
Python 字典實現原理
a a key1 1 a key2 6 del a key1 python直譯器 執行 a python直譯器讀到這裡,比如會給5個連續的記憶體空間,有5個連續的記憶體位址,可以放資料 python直譯器 執行 a key1 1 這裡,python直譯器會對key1進行雜湊運算,得到乙個十位進製的雜...
Python字典的實現原理
python中的字典底層依靠雜湊表 hash table 實現,使用開放定址法解決衝突,雜湊表是key value型別的資料結構,可以理解為乙個鍵值需要按照一定規則存放的陣列,而雜湊函式就是這個規則 字典本質上是乙個雜湊表 總有空白元素的陣列,python至少保證1 3的陣列是空的 字典中的每個鍵都...