为什么使用哈希而不是测试真正的平等?

时间:2013-11-28 14:42:26

标签: python dictionary hash

我最近一直在研究Python的词典(我相信它们在其他语言中被称为关联数组)并且被其键的一些限制所困惑。

首先,dict键必须是不可变的。当我查看其背后的逻辑时,答案是字典像哈希表一样查找键的值,因此不可变键(如果它们可以被清除)可能会改变它们的哈希值,从而在检索值时导致问题

我理解为什么会这样,但是我仍然对使用哈希表的意义感到困惑。如果你只是没有散列密钥并测试真正的相等性(假设压缩构造的对象比较相等),你可以复制字典的大部分功能而不受限制只使用两个列表。

所以,我想这是我真正的问题 - 使用哈希来查找价值而不是平等的理由是什么?

如果我不得不猜测,可能只是因为比较整数非常快且优化,而比较其他类的实例可能不是。

2 个答案:

答案 0 :(得分:9)

你似乎错过了散列表的全部内容,即快速(O(1)) 1 检索,并且没有散列就无法实现,即将密钥转换为某些一种分布均匀的整数,用作表的索引。请注意,为了能够处理哈希冲突 2 ,检索仍然需要相等,但只有在已经将元素集缩小到具有特定哈希值的元素时才会求助。

如果只是相等,你可以用并行数组或类似的东西复制类似的功能,但这会使检索O(n) 3 ;如果你要求严格的弱排序,你可以实现RB树,允许O(log n)检索。但是O(1)需要散列。

查看Wikipedia以获得有关哈希表的更多信息。


备注

  1. 它可以在病态场景中变成O(n)(所有元素都放在同一个桶中),但是不应该用良好的散列函数来实现。
  2. 由于不同的元素可能具有相同的哈希值,因此在访问与哈希对应的存储区后,您必须检查是否实际检索了与给定密钥关联的元素。
  3. 或者O(log n)如果你对数组进行排序,但是这会使插入变得复杂,由于元素的移动,插入变得平均为O(n);但话又说回来,如果你有订单,你可能想要一个RB树或堆。

答案 1 :(得分:1)

通过使用hastables,您可以获得O(1)个检索数据,而在每个独立的vale中进行比较时,需要O(n)(在顺序搜索中)或O(log(n))在二进制搜索中。

另请注意,O(1)是分摊的时间,因为如果有多个值散列到同一个键,则需要在这些值中进行顺序搜索。