【问题标题】:Is there another way to avoid duplication of large hashable objects?是否有另一种方法可以避免大型可散列对象的重复?
【发布时间】:2013-08-23 19:17:49
【问题描述】:

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

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 的返回值可用于返回唯一值。只是看起来有点笨拙。有没有更好、更 Pythonic 的方式来处理这种情况?

我对这个问题一直模棱两可。有两个问题 - 一个是我有数百万个对象当前正在使用从 100 到 1000 字节的键(big_hashable 的东西)。将它们转换为整数将能够处理比我目前更多的数据。其次,只保留每个 big_hashable 事物的单个规范副本也会减少内存使用量,尽管这是引发我的问题的第一个问题,因为每个键实际上都是 big_hashable 事物的单独副本。

【问题讨论】:

  • 您不只是使用 Python 集的任何特殊原因?
  • @PeterDeGlopper:您可以测试一个对象是否在一个集合中,但您无法有效地检索该集合的对象副本。
  • 也就是说,我不确定这个问题是否需要该功能。起初,我将其解释为类似于字符串实习,在这种情况下,您希望能够有效地检索对象的规范副本,但现在我不确定。
  • @user2357112 是的,虽然我在问题中没有看到对此的要求(虽然我可以想到可能很重要的情况,但我想不出任何 good 用例)。无论如何,如果您需要,您可以使用 dict 并将规范对象存储为值。
  • @delnan:在我看来,OP 想要存储一系列大的、可散列的对象,其中一些可能是相等的,并且只想使用相等对象的一个​​副本。这将需要检索规范副本的能力。也就是说,这可能是过早的优化。

标签: python duplication hashable


【解决方案1】:

如果您不需要在给定不同副本的情况下有效地检索对象的规范副本,则可以只使用一个集合:

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 函数对字符串所做的那样。

【讨论】:

  • 让我澄清一下问题及其原因。我很抱歉一开始就没有更清楚。
  • 类实习生解决了我的问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 2016-11-09
  • 1970-01-01
相关资源
最近更新 更多