簡體   English   中英

Python - 關於哈希和“無”的問題

[英]Python - question about hashes and `None`

為什么None哈希到-1042159082 (我發現它等於技嘉中的字節數否定)?

我意識到這並沒有真正影響我的代碼,但我很好奇。

哈希用於字典鍵查找,所以我決定嘗試:

>>> D = {-1042159082: 'Hello', None: 'Hi'}
>>> D[None]
'Hi'
>>> D[-1042159082]
'Hello'
>>>

我理解這是因為Python看到兩個相同的哈希,然后檢查類型以查看它是什么。 那正確嗎?

>>> {False: 'Hello', 0: 'Hi'}
{False: 'Hi'}
>>> {0: 'Hi', False: 'Hello'}
{0: 'Hello'}

這很奇怪。 更重要的是保留第一個鍵,保留第二個鍵。

這是巫術,還是有人能幫助我理解?

傳遞給內置hash()函數時可能產生相同輸出的大約2個值(問題中為None-1042159082 ):

這稱為沖突 (有關沖突的更多信息,請參閱Wikipedia上的頁面)。

Python使用的散列算法有一種特殊的方法可以確定出現沖突時人們真正想要的值(從第51行開始,請參閱CPython源代碼中的頁面(主要的Python解釋器),了解有關沖突的信息對於dicts,在撰寫本答案時; 文件還記錄了如何實現dicts)。

關於0False (以及更有用的信息)會發生什么,請參閱當前問題的其他答案。

您不能也不應該依賴於Python對象的特定哈希值。 它依賴於實現和機器。 在我的機器上:

>>> hash(None)
268532216

就填充dict對象而言(Python中沒有hash對象),或許以下內容將有所幫助:

>>> False == 0
True
>>> {0: 'Hello', 0: 'Hi'}
{0: 'Hi'}
>>> {0: 'Hi', 0: 'Hello'}
{0: 'Hello'}
>>> {False: 'Hello', False: 'Hi'}
{False: 'Hi'}
>>> {False: 'Hi', False: 'Hello'}
{False: 'Hello'}

使用dict構造函數時,您提供兩個key=value對,但它們都具有相同的鍵(即hashable值),因此,因為dict中的鍵值必須是唯一的,所以最后一個值是保存的值。 換句話說,上面的每個構造函數都創建了一個單項dict:

>>> print {False: 'Hello', 0: 'Hi'}
{False: 'Hi'}

有關詳細信息,請參見此處

不,即使兩個對象恰好具有相同的哈希值,它們仍然不會導致密鑰沖突。 Python檢測到這個並解決它(雖然請不要問我怎么做)。

但是False0相同而True1相同,因此當您在dict構造中使用兩者時,在使用相同的鍵添加另一個項時,您將更新該值。

你如何計算沒有哈希到那個值?

>>> d = {None:'hi'}
>>> d.get(-1042159082)
>>> d.get(None)
'hi'
>>>
>>> hash(None)
268532214
>>>

我不會依賴哈希值的值。

至於使用文字的字典解析,我假設在內部,定義一個'等於'另一個的鍵,將只進行更新而不是直接添加。

>>> class Key(object):
...     key = '1'
...     def __hash__(self):
...         return 1
...     def __eq__(self, other):
...         return hash(self) == hash(other)
... 
>>> class FakeKey(Key):
...     key = '2'
... 
>>> k = Key()
>>> >>> fk = FakeKey()
>>> d = {k:k,fk:fk}
>>> d
{<__main__.Key object at 0x100489f10>: <__main__.FakeKey object at 0x100489fd0>}
>>> ref = d[k]
>>> ref.key
'2'
>>> d.keys()[0].key
'1'
>>> 

出現我是對的(僅出現)。

暫無
暫無

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

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