簡體   English   中英

Python的哈希函數順序背后的邏輯是什么?

[英]What's the logic behind Python's hash function order?

眾所周知,某些Python的數據結構使用哈希表來存儲setdictionary等項目。 因此,這些對象沒有順序。 但是,對於某些數字序列而言,似乎並非如此。

例如,請考慮以下示例:

>>> set([7,2,5,3,6])
set([2, 3, 5, 6, 7])

>>> set([4,5,3,0,1,2])
set([0, 1, 2, 3, 4, 5])

但是,如果我們進行一些小的更改,則無法排序:

>>> set([8,2,5,3,6])
set([8, 2, 3, 5, 6])

所以問題是:Python的哈希函數如何在整數序列上工作?

盡管在SO中有很多關於hash及其順序的問題,但是沒有人解釋哈希函數的算法。

因此,這里您所需要的就是知道python如何計算哈希表中的索引。

如果您瀏覽CPython源代碼中的hashtable.c文件,您將在_Py_hashtable_set函數中看到以下幾行,該行顯示python計算哈希表鍵索引的方式:

key_hash = ht->hash_func(key);
index = key_hash & (ht->num_buckets - 1);

因此,由於整數的哈希值本身就是整數*(-1除外),因此索引基於數據結構的數量和長度( ht->num_buckets - 1 ),並且按位計算-和(ht->num_buckets - 1)和數字。

現在考慮以下使用hash-table的set示例:

>>> set([0,1919,2000,3,45,33,333,5])
set([0, 33, 3, 5, 45, 333, 2000, 1919])

對於數字33我們有:

33 & (ht->num_buckets - 1) = 1

實際上是:

'0b100001' & '0b111'= '0b1' # 1 the index of 33

注意在這種情況下(ht->num_buckets - 1)8-1=70b111

1919

'0b11101111111' & '0b111' = '0b111' # 7 the index of 1919

而對於333

'0b101001101' & '0b111' = '0b101' # 5 the index of 333

以及上述示例:

>>> set([8,2,5,3,6])
set([8, 2, 3, 5, 6])

'0b1000' & '0b100'='0b0' # for 8
'0b110' & '0b100'='0b100' # for 8

*類int的哈希函數:

class int:
    def __hash__(self):
        value = self
        if value == -1:
            value = -2
        return value

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM