查找表在Python中不可用 [英] Lookup table for unhashable in Python

查看:137
本文介绍了查找表在Python中不可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. 我可以使对象可哈希。我不知道我会如何做到这一点。我知道我可以实现 __ hash __(),但我不确定如何实际计算散列(应该是整数)。


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


在我看来,想要查找不可查询将是一个常见问题,所以我认为有人已经解决了这个问题。有关如何为类似字典的对象实现 __ hash()__ 的任何建议,或者是否有其他标准方法来制作查找表的不可匹配?

解决方案

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



如果你的对象是字典,你可以使用 frozenset 所有的键值对。

  def __hash __(self):
return hash(frozenset(self.iteritems()))

只有所有值都是可散列的,这才有效。为了保存哈希的重新计算(这将在每次查找时完成),您可以缓存哈希值,并在重新计算时设置脏标志。


I need to create a mapping from objects of my own custom class (derived from dict) to objects of another custom class. As I see it there are two ways of doing this:

  1. I can make the objects hashable. I'm not sure how I would do this. I know I can implement __hash__() but I'm unsure how to actually calculate the hash (which should be an integer).

  2. Since my objects can be compared I can make a list [(myobj, myotherobj)] and then implement a lookup which finds the tuple where the first item in the tuple is the same as the lookup key. Implementing this is trivial (the number of objects is small) but I want to avoid reinventing the wheel if something like this already exists in the standard library.

It seems to me that wanting to look up unhashables would be a common problem so I assume someone has already solved this problem. Any suggestions on how to implement __hash()__ for a dict-like object or if there is some other standard way of making lookup tables of unhashables?

解决方案

Mappings with mutable objects as keys are generally difficult. Is that really what you want? If you consider your objects to be immutable (there is no way to really enforce immutability in Python), or you know they will not be changed while they are used as keys in a mapping, you can implement your own hash-function for them in several ways. For instance, if your object only has hashable data-members, you can return the hash of a tuple of all data-members as the objects hash.

If your object is a dict-like, you can use the hash of a frozenset of all key-value-pairs.

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

This only works if all values are hashable. In order to save recalculations of the hashes (which would be done on every lookup), you can cache the hash-value and just recalculate it if some dirty-flag is set.

这篇关于查找表在Python中不可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆