【问题标题】:Objects have same hash, dictionary not recognizing as same对象具有相同的哈希,字典不识别为相同
【发布时间】:2013-06-28 01:53:15
【问题描述】:

我有两个对象代表同一个对象。我什至保证他们有相同的哈希值。我仍然从字典中得到一个错误:

>>> hash(one)
1098414562
>>> hash(one+zero)
1098414562
>>> a={one:1}
>>> a[one+zero]

Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    a[one+zero]
KeyError: {{|}|}

我还需要做什么来确保字典将其重新识别为相同的键?

【问题讨论】:

    标签: python dictionary hashtable


    【解决方案1】:

    要正确地成为hashable dict 键,对象还必须定义__eq__()__cmp__()。它们必须比较相等才能被识别为相同的键。

    如果对象具有相同的哈希,但比较不相等,则假设哈希冲突,并且它们在同一个哈希桶中分开。

    当通过hash查找对象时,匹配的hash桶中的所有对象都与它进行比较,如果没有相等,则为KeyError。

    【讨论】:

    • 我忘记了__eq__中的return语句。
    【解决方案2】:

    如果一个类没有定义__cmp__()__eq__() 方法,它也不应该定义__hash__() 操作;如果它定义了__cmp__()__eq__() 而不是__hash__(),则它的实例将无法在散列集合中使用。如果一个类定义了可变对象并实现了__cmp__()__eq__()方法,它不应该实现__hash__(),因为可哈希集合实现要求对象的哈希值是不可变的(如果对象的哈希值发生变化,它将在错误的哈希桶)。

    source

    【讨论】:

      【解决方案3】:

      这称为哈希冲突。散列只是在字典中分配键的一种相对有效的方式。它不保证唯一性。当你查找一个key时,需要考虑所有具有匹配hash的key,并会使用__eq__方法来判断它们是否真的匹配。

      除此之外: 可能有一个类总是为它的任何实例返回相同的哈希值。然而,这破坏了通常的O(1) 查找复杂性

      您可以通过在此处尝试不同的 n 值来轻松查看线性时间查找

      class MyInt(int):
          def __hash__(self):
              return hash(1)
      
      d = {MyInt(i): i for i in xrange(n)}
      
      d[MyInt(1)]  # This will take O(n) time since all values have the same hash
      

      【讨论】:

        猜你喜欢
        • 2013-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-23
        相关资源
        最近更新 更多