Making a list subclass hashable [closed]

半城伤御伤魂 提交于 2019-12-13 02:49:32

问题


I want to derive a class from list, add a few instance attributes to it, and make it hashable. What is a good (fast and neat) way to do it?

UPDATE:

I deleted a lengthy explanation of a use case. I also moved a related but separate issue into a different question.


回答1:


This code is fine. You're making a copy of the list, which could be a bit slow.

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

You have several options if you want to be faster.

  • Store list_attribute as a tuple, not a list (after it is fully constructed)
  • Compute the hash once at init time and store the hash value. You can do this because your class is immutable, so the hash will never change.
  • Write your own hash function. Here's the hash function for tuple, do something similar.



回答2:


You can apply tuple to self:

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

tuple-ing self takes about half the time of the whole hashing process:

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))

prints

0.9382011891054844
0.3911763069244216



回答3:


This is more of a comment than an answer, but it's too long to be a comment. This is how one can accesses instance attributes from inside __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


来源:https://stackoverflow.com/questions/10253783/making-a-list-subclass-hashable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!