可能重复:
当一个Python对象的哈希计算,为什么是-1不同的哈希?
为什么-1
和-2
都哈希到同一个号码,如果Python的?
既然他们这样做,Python是怎样分辨这两个数字?
>>> -1 is -2
False
>>> hash(-1) is hash(-2)
True
>>> hash(-1)
-2
>>> hash(-2)
-2
可能重复:
当一个Python对象的哈希计算,为什么是-1不同的哈希?
为什么-1
和-2
都哈希到同一个号码,如果Python的?
既然他们这样做,Python是怎样分辨这两个数字?
>>> -1 is -2
False
>>> hash(-1) is hash(-2)
True
>>> hash(-1)
-2
>>> hash(-2)
-2
-1
是在CPython的的C水平,其防止散列函数从能够产生的散列值的保留值-1
。 正如帝斯曼指出,同样是不正确的IronPython和PyPy其中hash(-1) != hash(-2)
见这Quora的答案 :
如果你写一个C扩展模块中的类型,并提供一个
tp_hash
方法,你必须避免-1
-如果返回-1
,Python会假定你的意思是抛出一个错误。如果你写在纯Python类,并提供一个
__hash__
方法,有没有这样的规定,谢天谢地。 但是,这是因为调用你的C代码__hash__
方法会为你-如果你的__hash__
返回-1
,则hash()
应用到你的对象实际上将返回-2
。
这真的只是从重新打包的信息effbot :
哈希值
-1
被保留(它是用来标记错误的C实现)。 如果散列算法生成此值,我们简单地使用-2
代替。
您还可以看到这个源。 例如,对于Python 3中的int
对象,这是在端部的散列执行 :
if (x == (Py_uhash_t)-1)
x = (Py_uhash_t)-2;
return (Py_hash_t)x;
既然他们这样做,Python是怎样分辨这两个数字?
因为所有哈希函数映射一个大的输入空间,以更小的输入空间,碰撞总是预期,哈希函数再好的。 想想散列字符串,例如。 如果散列码是32位整数,你有2 ^ 32(略超过4十亿)的散列码。 如果考虑长度为6的所有ASCII字符串,你有(2 ^ 7)^ 6(不到4.4万亿),不同的项目在你的输入空间。 由于只有这一套,你保证有很多很多的碰撞不管你有多好。 加入Unicode字符和无限长度的字符串到!
因此,散列代码只暗示一个对象的位置,一个相等测试如下测试候选键。 为了实现在哈希表集的成员资格测试,哈希码给出其中搜索的价值你“斗”号。 然而,相同的散列码所有设置项目都在斗。 对于这一点,你还需要一个平等的测试在桶中的所有考生进行区分。
该散列码与平等偶是在暗示中的哈希的对象CPython的文档 。 在其他语言/框架,有一个准则/规则,如果你提供一个自定义的散列码功能,还必须提供自定义的平等测试(在相同的字段作为哈希函数的代码执行)。
事实上,Python的今天发布的地址正是这一点,与当这(散列值相同,但大规模)作为服务拒绝攻击,解决效率问题,安全补丁- http://mail.python.org /pipermail/python-list/2012-April/1290792.html