在Python中无法哈希的查找表


问题内容

我需要创建一个从我自己的自定义类(从dict派生)到另一个自定义类的对象的映射。如我所见,有两种方法可以做到这一点:

  1. 我可以使对象散列。我不确定该怎么做。我知道我可以实现,__hash__()但是我不确定如何实际计算哈希值(应该是整数)。

  2. 由于可以比较我的对象,因此我可以创建一个列表[(myobj,myotherobj)],然后实施查找以查找元组,其中元组中的第一项与查找键相同。实现这一点很简单(对象的数量很小),但是如果标准库中已经存在类似的东西,我想避免重新发明轮子。

在我看来,想要查找不可哈希的对象将是一个常见问题,因此我认为有人已经解决了这个问题。关于如何实现__hash()__类似dict的对象的建议,或者是否存在其他一些创建不可哈希表的标准方法?


问题答案:

以可变对象作为键的映射通常很困难。那真的是你想要的吗?如果您认为对象是不可变的(在Python中无法真正实现不可变性),或者您知道在将它们用作映射的键​​时它们不会被更改,则可以在其中实现自己的哈希函数几种方法。例如,如果您的对象仅具有可哈希的数据成员,则可以将所有数据成员的元组的哈希作为对象哈希返回。

如果您的对象是类似dict的对象,则可以使用所有键值对的冻结集的哈希。

def __hash__(self):
    return hash(frozenset(self.iteritems()))

仅当所有值都是可哈希的时,这才起作用。为了保存对哈希的重新计算(将在每次查找中完成),您可以缓存哈希值,如果设置了脏标志,则只需重新计算即可。