Python 有没有其他方法可以避免大型散列对象的重复?

Python 有没有其他方法可以避免大型散列对象的重复?,python,duplication,hashable,Python,Duplication,Hashable,我正在处理文本,需要存储大量可散列对象序列——有时是字符串,有时是单词元组,等等。我一直在考虑使用散列函数来提供一个简单的存储和检索类,但在我的第一种方法中,单个散列键可能解析为多个项。由于我添加了一个get函数,该函数将add的返回值作为参数,因此我无法知道要返回列表中的哪个项 class HashStore: def __init__(self): self.uniques = {} def add(self, big_hashable):

我正在处理文本,需要存储大量可散列对象序列——有时是字符串,有时是单词元组,等等。我一直在考虑使用散列函数来提供一个简单的存储和检索类,但在我的第一种方法中,单个散列键可能解析为多个项。由于我添加了一个get函数,该函数将add的返回值作为参数,因此我无法知道要返回列表中的哪个项

class HashStore:
    def __init__(self):
        self.uniques = {}

    def add(self, big_hashable):
        hash_value = hash(big_hashable)
        if hash_value not in self.uniques:
            self.uniques[hash_value] = [big_hashable]
        elif big_hashable not in self.uniques[hash_value]:
            self.uniques[hash_value].append(big_hashable)

        return hash_value
另一种方法最终确保每个唯一的可散列项只有一个映射

class SingleStore:
    def __init__(self):
        self.uniques = {}
        self.indexed = {}
        self.index = 0

    def add(self, big_hashable):
        if big_hashable not in self.uniques:
            self.index += 1
            self.uniques[big_hashable] = self.index
            self.indexed[self.index] = big_hashable

        return self.uniques[big_hashable]
这样做可以确保add的返回值可以用于返回唯一的值。这看起来有点笨拙。有没有一种更好、更像蟒蛇的方式来处理这种情况


我对这个问题一直模棱两可。有两个问题——一个是我有数百万个对象,它们当前使用的密钥范围从100字节到1000字节不等(大散列)。将这些转换为整数将使我能够处理比目前更多的数据。其次,只保留每个大的可散列对象的一个规范副本也会减少内存使用,尽管这是促使我提出问题的第一个问题,因为每个键实际上都是大散列对象的一个单独副本。

如果您不需要高效地检索给定不同副本的对象的规范副本,您可以使用一组:

s = set()
s.add(3)
s.add(3)
# s only has one 3 in it
如果您确实需要能够高效地检索对象的规范副本,请不要按哈希值存储它们,否则会严重损坏。直接使用hashable

class Interner(object):
    def __init__(self):
        self._store = {}
    def canonical_object(self, thing):
        """Returns a canonical object equal to thing.

        Always returns the same result for equal things.

        """

        return self._store.setdefault(thing, thing)

使用
weakref
模块,您可以改进这一点,在客户端代码放弃规范对象时不保留它,就像内置的
intern
函数对字符串所做的那样。

您不只是使用Python集有什么特殊原因吗?@PeterDeGlopper:您可以测试对象是否在一个集中,但是您无法有效地检索对象集的副本。也就是说,我不确定问题是否需要该功能。起初,我将其解释为类似字符串实习,在这种情况下,您可能希望能够有效地检索对象的规范副本,但现在我不确定。@user2357112 True,尽管我在问题中没有看到这方面的要求(虽然我可以想到这可能很重要的情况,但我想不出任何好的用例). 在任何情况下,如果您需要,您只需使用dict并将规范对象存储为值。@delnan:在我看来,OP希望存储一系列大型可散列对象,其中一些对象可能是相等的,并且只希望使用相等对象的一个副本。这需要能够检索规范副本。也就是说,这可能是过早的优化。让我澄清一下问题和原因。我很抱歉一开始没有说得更清楚。课堂实习生回答了我的问题。非常感谢。