通过哈希查找set中的项目

时间:2015-02-03 15:04:25

标签: python hash set

如果我知道如何计算哈希值,是否有快速查找集合对象的方法?

我有以下类,uid是一个唯一的字符串(从不对不同的对象使用过两次):

class Foo():
    def __init__(self, uid):
        self.uid = uid
        self.__hash = hash(self.uid)

    def __hash__(self):
        return self.__hash

    def __eq__(self, other):
        return self.__hash == other.__hash

我创建了一个使用不同uid s:

创建的集合
foos = {Foo('a'), Foo('b'), Foo('c')}

我现在想知道,如果我想要使用b初始化的项目,如果有更快的(如果可能更多的pythonic)方式从集合中获取元素而不是

b_object = next(foo for foo in foos if foo.uid == 'b')

因为我可以得到hash_b = hash('b'),这应该提供更快的访问权限,如果该集合非常大(在我的特殊情况下显然是这种情况)。

1 个答案:

答案 0 :(得分:1)

我不确定您使用此功能,但您可以执行以下操作:

uid_to_foo = {foo.uid: foo for foo in foos}

# use 'uid_to_foo[some_foo.uid]' to find an instance fast

现在,您可以通过它Foo快速访问任何uid个实例。

请注意,您当前的哈希不会承诺没有冲突(尽管可能不太可能)。

你甚至可以在课堂上拥有这个:

class Foo():

    # add class dictionary mapping uids to foos
    uid_to_foo = {}

    def __init__(self, uid):
        self.uid = uid
        self.__hash = hash(self.uid)

        # add to class-level mapping
        Foo.uid_to_foo[uid] = self

    def __hash__(self):
        return self.__hash

    def __eq__(self, other):
        return self.__hash == other.__hash

要为每个子类创建映射,您可以使用defaultdict执行类似(如评论中所述)的操作:

class Base():

    # add class dictionary mapping uids to instances
    uid_to_obj = defaultdict(dict)

    def __init__(self, uid):
        self.uid = uid
        self.__hash = hash(self.uid)

        # add specific sub-class mapping for each sub-class
        Foo.uid_to_obj[type(self).__name__][uid] = self

    def __hash__(self):
        return self.__hash

    def __eq__(self, other):
        return self.__hash == other.__hash

特定于类的词典现在明显位于Foo.uid_to_obj[type(self).__name__]