使列表子类可哈希

时间:2012-04-20 21:26:24

标签: python list python-3.x immutability hashable

我想从list派生一个类,为它添加一些实例属性,并使其可以删除。什么是好(快速和整洁)的方式呢?

更新:

我删除了一个用例的冗长解释。我还将一个相关但又分开的问题移到different question

3 个答案:

答案 0 :(得分:1)

这段代码很好。你正在复制列表,这可能有点慢。

def __hash__(self):
    return hash(tuple(self.list_attribute))

如果你想加快速度,你有几个选择。

  • list_attribute存储为元组,而不是列表(完全构建后)
  • init 时计算一次哈希并存储哈希值。你可以这样做,因为你的类是不可变的,所以哈希永远不会改变。
  • 编写自己的哈希函数。这是hash function for tuple,做类似的事情。

答案 1 :(得分:1)

您可以将tuple应用于self

class State(list):
    def __hash__(self):
        return hash((self.some_attribute, tuple(self)))

tuple - self占整个哈希过程的一半时间:

from timeit import timeit

setup = "from __main__ import State; s = State(range(1000)); s.some_attribute = 'foo'"
stmt = "hash(s)"
print(timeit(stmt=stmt, setup=setup, number=100000))

setup = "r = list(range(1000))"
stmt = "tuple(r)"
print(timeit(stmt=stmt, setup=setup, number=100000))

打印

0.9382011891054844
0.3911763069244216

答案 2 :(得分:1)

这不仅仅是一个评论而是一个答案,但是评论太长了。这就是人们可以从__new__内部访问实例属性的方法:

class Data(tuple):
    def __new__(klass, arg):
        data_inst = tuple.__new__(klass, arg)
        data_inst.min = min(data_inst)
        data_inst.max = max(data_inst)
        return data_inst

>>> d = Data([1,2,3,4])
>>> d
(1, 2, 3, 4)
>>> d.min
1
>>> d.max
4
>>> d1 = Data([1,2,3,4,5,6])
>>> d1.max
6
>>> d.max
4