python 用雜湊表來實現 dict。雜湊表其實是乙個稀疏陣列(總是有空白元素的陣列稱為稀疏陣列)。在一般書中,雜湊表裡的單元通常叫做表元(bucket)。在 dict 的雜湊表當中,每個鍵值對都占用乙個表元,每個表元都有兩個部分,乙個是對鍵的引用,乙個是對值的引用。因為每個表元的大小一致,所以可以通過偏移量來讀取某個表元。
python 會設法保證大概還有三分之一的表元是空的,當快要達到這個閥值的時候,會進行擴容,將原雜湊表複製到乙個更大的雜湊表裡。
如果要把乙個物件放入到雜湊表裡,就先要計算這個元素鍵的雜湊值。這就要求鍵(key)必須是可雜湊的。
乙個可雜湊的物件必須滿足以下條件:
為了獲取鍵search_key
所對應的值search_value
,python 會首先呼叫hash(search_key)
計算search_key
的雜湊值,把這個值最低的幾位數字當作偏移量,在雜湊表裡查詢表元(具體取幾位,得看當前雜湊表的大小)。若找到的表元是空的,則丟擲keyerror
異常;若不為空,則表元裡會有一對found_key
:found_value
,檢驗search_key
和found_key
是否相等,若相等,則返回found_value
。若不相等,這種情況稱為雜湊衝突。
為了解決雜湊衝突,演算法會在雜湊值中另外再取幾位,然後用特殊的方法處理一下,把得到的新數值作為偏移量在雜湊表中查詢表元,若找到的表元是空的,則同樣丟擲 keyerror 異常;若非空,則比較鍵是否一致,一致則返回對應的值;若又發現雜湊衝突,則重複以上步驟。
新增新元素跟上面的過程幾乎一樣,只不過在發現空表元的時候會放入這個新元素,不為空則為雜湊衝突,繼續查詢。
當往 dict 裡新增新元素並且發生了雜湊衝突的時候,新元素可能會被安排存放到另乙個位置。於是就會發生下面的情況:dict([key1, value1], [key2, value2])
和dict([key2, value2], [key1, value1])
兩個字典,在進行比較的時候是相等的,但如果 key1 和 key2 雜湊衝突,則這兩個鍵在字典裡的順序是不一樣的(因為新增的順序不一樣,先新增的先佔據第一次雜湊值的位置,後新增的)。
無論何時,往 dict 裡新增新的鍵,python 解析器都可能做出為字典擴容的決定。擴容導致的結果就是要新建乙個更大的雜湊表,並把字典裡已有的元素新增到新的雜湊表裡。這個過程中可能發生新的雜湊衝突,導致新雜湊表中鍵的次序變化。
雜湊表是乙個在時間和空間上做出權衡的經典例子。如果沒有空間(記憶體)的限制,那麼可以直接將鍵作為陣列的索引。那麼所有的查詢時間複雜度為 o(1);如果沒有時間的限制,那麼可以直接用陣列,這樣只需要很少的記憶體。字典與雜湊表
一 字典 字典 dictionary 是一些元素的集合。每個元素有乙個稱作key 的域,不同元素的key各 不相同。有關字典的操作有 插入具有給定關鍵字值的元素。在字典中尋找具有給定關鍵字值的元素。刪除具有給定關鍵字值的元素。隨機訪問 若僅按照乙個字典元素本身的關鍵字來訪問該元素。順序訪問 指按照關...
字典和雜湊表
在字典 或對映 中,用 鍵 值 對的形式來儲存資料。如果item變數是乙個物件的話,需要實現tostring方法,否則會導致出現異常的輸出結果,如 object object function defaulttostring item else if item undefined else if t...
雜湊表與雜湊函式
雜湊表 我們將任意型別元素轉換為整型的過程叫作雜湊。所謂雜湊,實質上是高維空間向低維空間的對映。高維度空間元素數量多,低維空間元素數量少,必定會出現多對一的對映,所以必然出現雜湊衝突。在設計雜湊函式的過程要針對狀態數來進行分析。雜湊函式的本質在做雜湊,處理雜湊碰撞。設計雜湊表應當注重以下兩點 設計雜...