【问题标题】:Why hash function on two different objects return same value?为什么两个不同对象的哈希函数返回相同的值?
【发布时间】:2016-07-14 08:35:11
【问题描述】:

我使用 Spyder,运行 Python 2.7。

刚刚发现有趣的东西:

  1. hash(-1) 和hash(-2) 都返回-2,有问题吗?我虽然不同对象上的哈希函数应该返回不同的值。我读过以前的帖子, -1 在 Python 中被保留为错误。
  2. hash('s') 返回 1835142386,然后 hash(1835142386) 返回相同的值。这是另一个问题吗?

谢谢。

【问题讨论】:

  • "我虽然不同对象的哈希函数应该返回不同的值" --- 不,它只应该为同一个对象返回相同的值。
  • 哈希不保证唯一性。
  • 奇怪的是,除了 -1,hash(i) == i 之外的 abs(i) <= 1,000,000

标签: python hash


【解决方案1】:

-1 在 Python 中不是“保留为错误”。不知道这甚至意味着什么。如果不允许使用-1,则有大量程序无法简单清晰地编写。

“有问题吗?”不。散列函数不需要为每个对象返回不同的散列。事实上,这是不可能的,因为可能的对象比哈希值多得多。 CPython 的hash() 有一个很好的属性,它可以将非负数的参数返回到sys.maxint,这就是为什么在你的第二个问题hash(hash('s')) == hash('s') 中,但这是一个实现细节。

-1 和 -2 具有相同的散列这一事实仅仅意味着使用这些值作为例如字典键将导致散列冲突。哈希冲突是预期的情况,由 Python 自动解决,添加的第二个键将简单地进入字典中的下一个可用槽。访问第二个插入的密钥会比访问另一个密钥稍慢,但在大多数情况下,速度不会足够您会注意到。

可以构造大量具有相同哈希值的不相等对象,当存储在字典或集合中时,会导致容器的性能大幅下降,因为添加的每个对象都会导致哈希碰撞,但除非你去寻找它,否则你不会遇到它。

【讨论】:

  • 如果-1 值没有被保留(对于某些东西) - 它作为异常的实际目的是什么? github.com/python/cpython/blob/…
  • 嗯,似乎它确实表示错误:github.com/python/cpython/blob/…“所有实用程序函数 (_Py_Hash*()) 返回“-1”表示错误。”
  • 是的,如果哈希函数不能保证唯一性(这是有道理的,对象比整数多),每次我添加一个新键时,如果哈希值返回一个值,即巧合,和之前key的值一样,系统会修复的吧?这是有道理的。谢谢。
  • 啊哈。我没有意识到您正在查看哈希函数 C 代码。这是有道理的,内部会有一个值用作错误代码,并且还解释了为什么 -1 的哈希不是 -1。今天学到了一些东西!谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-02-08
  • 2015-08-12
  • 2013-03-26
  • 2012-08-13
  • 2014-11-30
  • 2019-10-30
  • 2014-08-11
  • 1970-01-01
相关资源
最近更新 更多