Python字典的實現原理

2022-04-10 14:49:33 字數 1526 閱讀 4314

python中的字典底層依靠雜湊表(hash table)實現, 使用開放定址法解決衝突,

雜湊表是key-value型別的資料結構, 可以理解為乙個鍵值需要按照一定規則存放的陣列, 而雜湊函式就是這個規則

字典本質上是乙個雜湊表(總有空白元素的陣列, python至少保證1/3的陣列是空的), 字典中的每個鍵都占用乙個單元, 乙個單元分為兩部分, 分別是對鍵的引用和對值的引用, 使用hash函式獲得鍵的雜湊值, 雜湊值對陣列長度取餘, 取得的值就是存放位置的索引

雜湊衝突(陣列的索引相同), 使用開放定址法解決

這也是python中要求字典的key必須可hash的原因

陣列中1/3的位置為空, 增加元素可能會導致擴容, 引發新的雜湊衝突, 導致新的雜湊表中鍵的次序發生變化, 這也是字典遍歷時不能新增和刪除的原因

字典在記憶體中開銷很大, 實際上是以空間換時間

根據設定的雜湊函式h(key)和處理衝突方法將一組關鍵字映象到乙個有限的位址區間上的演算法。也稱為雜湊演算法、雜湊演算法。

資料經過雜湊演算法之後得到的集合。這樣關鍵字和資料在集合中的位置存在一定的關係,可以根據這種關係快速查詢。

與雜湊表相對應,集合中的 資料和其存放位置沒任何關聯關係的集合。

由此可見,雜湊演算法是一種特殊的演算法,能將任意資料雜湊後對映到有限的空間上,通常計算機軟體中用作快速查詢或加密使用。

由於雜湊演算法被計算的資料是無限的,而計算後的結果範圍有限,因此總會存在不同的資料經過計算後得到的值相同,這就是雜湊衝突。

從發生衝突的那個單元起,按照一定的次序,從雜湊表中找到乙個空閒的單元。然後把發生衝突的元素存入到該單元的一種方法。開放定址法需要的表長度要大於等於所需要存放的元素。

在開放定址法中解決衝突的方法有:線行探查法、平方探查法、雙雜湊函式探查法。

開放定址法的缺點在於刪除元素的時候不能真的刪除,否則會引起查詢錯誤,只能做乙個特殊標記。只到有下個元素插入才能真正刪除該元素。

鏈結位址法的思路是將雜湊值相同的元素構成乙個同義詞的單鏈表,並將單鏈表的頭指標存放在雜湊表的第i個單元中,查詢、插入和刪除主要在同義詞鍊錶中進行。鍊錶法適用於經常進行插入和刪除的情況。

如下一組數字,(32、40、36、53、16、46、71、27、42、24、49、64)雜湊表長度為13,雜湊函式為h(key)=key%13,則鍊錶法結果如下:

0       

1 -> 40 -> 27 -> 53

23 -> 16 -> 4245

6 -> 32 -> 71

7 -> 4689

10 -> 36 -> 49

11 -> 24

12 -> 64

就是同時構造多個不同的雜湊函式:

hi = rhi(key) i= 1,2,3 ... k;

當h1 = rh1(key) 發生衝突時,再用h2 = rh2(key) 進行計算,直到衝突不再產生,這種方法不易產生聚集,但是增加了計算時間。

將雜湊表分為公共表和溢位表,當溢位發生時,將所有溢位資料統一放到溢位區。

Python 字典實現原理

a a key1 1 a key2 6 del a key1 python直譯器 執行 a python直譯器讀到這裡,比如會給5個連續的記憶體空間,有5個連續的記憶體位址,可以放資料 python直譯器 執行 a key1 1 這裡,python直譯器會對key1進行雜湊運算,得到乙個十位進製的雜...

Python字典物件實現原理

字典型別是python中最常用的資料型別之一,它是乙個鍵值對的集合,字典通過鍵來索引,關聯到相對的值,理論上它的查詢複雜度是 o 1 d d c 3 d 在字串的實現原理文章中,曾經出現過字典物件用於intern操作,那麼字典的內部結構是怎樣的呢?pydictobject物件就是dict的內部實現。...

Python字典物件實現原理

字典型別是python中最常用的資料型別之一,它是乙個鍵值對的集合,字典通過鍵來索引,關聯到相對的值,理論上它的查詢複雜度是 o 1 d d c 3 d 在字串的實現原理文章中,曾經出現過字典物件用於intern操作,那麼字典的內部結構是怎樣的呢?pydictobject物件就是dict的內部實現。...