Python字典的原理

2021-10-10 14:05:57 字數 2269 閱讀 9288

python中dict物件是表明了其是乙個原始的python資料型別,按照鍵值對的方式儲存,其中文名字翻譯為字典,顧名思義其通過鍵名查詢對應的值會有很高的效率,時間複雜度在常數級別o(1).本文針對其實現的資料結構進行原理性說明和拓展,不涉及python的原始碼剖析。

dict底層實現

在python2中,dict的底層是依靠雜湊表(hash table)進行實現的,使用開放位址法解決衝突.

所以其查詢的時間複雜度會是o(1),下文會具體講解雜湊表的工作原理和解決衝突時的具體方法。

雜湊表雜湊表是key-value型別的資料結構,通過關鍵碼值直接進行訪問。通過雜湊函式進行鍵和陣列的下標對映從而決定該鍵值應該放在哪個位置,**雜湊表可以理解為乙個鍵值需要按一定規則存放的陣列,而雜湊函式就是這個規則。**此處提出幾個專業名詞後面會一一進行介紹。

1. 雜湊函式2. 裝填因子3. 衝突

1.雜湊表產生的原因

假設我們存在乙個簡單的鍵值對結構,鍵-員工號,值-是否在崗。現在需要這樣乙個功能,輸入員工號,返回該員工是否在崗,理想的方法是建立乙個長度為max(員工號)的陣列,陣列下標就是員工號,陣列中的值用0和1對是否在崗進行區分,這樣只需要o(1)的時間複雜度就可以完成操作,但是擴充套件性不強,存在以下問題。

1.假設新進員工的員工號比max(員工號)還要大,這就需要重新申請陣列進行遷移操作。

2.假設一種極端的情況,存在兩個員工,員工號分別是1和100000000001,這樣子的話按照先前的設計思路,是會浪費很大的儲存空間的。

上面兩點,第一點是因為陣列的固定申請大小的屬性所決定,而第二點就是引入雜湊表的原因,會不會存在乙個方法,讓乙個大員工號變小而而且沒有標記,雜湊函式便產生,假設此處的雜湊規則是除3取模,則員工1得到的雜湊值是1,員工100000000001得到的雜湊值是2,這樣的話按照設計思路,只需要乙個大小為2的陣列便可以覆蓋了,這就是雜湊思想。

演算法中時間和空間是不能兼得的,雜湊表就是一種用合理的時間消耗去減少大量空間消耗的操作,這取決於具體的功能要求。

2.雜湊函式

上面的例子中雜湊函式的設計很隨意,但是從這個例子中我們也可以得到資訊:

雜湊函式就是乙個對映,因此雜湊函式的設定很靈活,只要使得任何關鍵字由此所得的雜湊函式值都落在表長允許的範圍之內即可;

並不是所有的輸入都只對應唯一乙個輸出,也就是雜湊函式不可能做成乙個一對一的對映關係,其本質是乙個多對一的對映,這也就引出了下面乙個概念–衝突。

3.衝突

只要不是一對一的對映關係,衝突就必然會發生,還是上面的極端例子,這時新加了乙個員工號為2的員工,先不考慮我們的陣列大小已經定為2了,按照之前的雜湊函式,工號為2的員工雜湊值也是2,這與100000000001的員工一樣了,這就是乙個衝突,針對不同的解決思路,提出三個不同的解決方法。

4.衝突解決方法

4.1 開放位址

開放位址的意思是除了雜湊函式得出的位址可用,當出現衝突的時候其他的位址也一樣可用,常見的開放位址思想的方法有線性探測再雜湊,二次探測再雜湊,這些方法都是在第一選擇被占用的情況下的解決方法。

4.2 再雜湊法

這個方法是按順序規定多個雜湊函式,每次查詢的時候按順序呼叫雜湊函式,呼叫到第乙個為空的時候返回不存在,呼叫到此鍵的時候返回其值。

4.3 鏈位址法

將所有關鍵字雜湊值相同的記錄都存在同一線性鍊錶中,這樣不需要占用其他的雜湊位址,相同的雜湊值在一條鍊錶上,按順序遍歷就可以找到。

4.4公共溢位區

其基本思想是:所有關鍵字和基本表中關鍵字為相同雜湊值的記錄,不管他們由雜湊函式得到的雜湊位址是什麼,一旦發生衝突,都填入溢位表。

5.裝填因子α

一般情況下,處理衝突方法相同的雜湊表,其平均查詢長度依賴於雜湊表的裝填因子。雜湊表的裝填因子定義為表中填入的記錄數和雜湊表長度的桌布,也就是標誌著雜湊表的裝滿程度。直**來,α越小,發生衝突的可能性就越小,反之越大。一般0.75比較合適,涉及數學推導。

實現細節

cpython使用偽隨機探測(pseudo-random probing)的雜湊表(hash table)作為字典的底層資料結構。由於這個實現細節,只有可雜湊的物件才能作為字典的鍵。

python中所有不可變的內建型別都是可雜湊的。

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

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

python字典的底層原理

無序,可變的容器資料結構,key value資料儲存 key可以為數值,字串,元組,但是唯一,value則支援多種資料型別 讀取速度快,時間複雜度o 1 o 1 o 1 python字典的底層實現是雜湊表,即帶有索引和儲存空間的表 如d 建立乙個空字典,初始化乙個長度為8 的c陣列arr 1.插入資...

Python字典的實現原理

python中的字典底層依靠雜湊表 hash table 實現,使用開放定址法解決衝突,雜湊表是key value型別的資料結構,可以理解為乙個鍵值需要按照一定規則存放的陣列,而雜湊函式就是這個規則 字典本質上是乙個雜湊表 總有空白元素的陣列,python至少保證1 3的陣列是空的 字典中的每個鍵都...

Python 字典實現原理

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