Python:在类上定义的哈希不会识别元组

时间:2013-01-29 13:09:01

标签: python class hash

我正在尝试实现建议的here哈希定义,但是在尝试在类上使用哈希时遇到错误。该类定义如下:

class Metabolite:
    def __init__(self, name_in='', id_in='', synonyms_in=[], InChIKey_in='', formulae_in=[], charge_in='', ecs_in=[], mtk_in = [],  mtb_in = '', mtm_in = '', mts_in = '', bkm_id_in = '', source_in = ''):
        self.name = name_in
        self.id = id_in
        self.formulae = formulae_in
        self.inchikey = InChIKey_in
        self.synonyms = synonyms_in
        self.charge = charge_in
        self.ecs = ecs_in
        self.mtb = mtb_in
        self.mtk = mtk_in
        self.mtm = mtm_in
        self.mts = mts_in
        self.bkm_id = bkm_id_in
        self.source = source_in

    def key(self):
        return self.id, self.inchikey, self.mts, self.mtk, self.mtb, self.mtk

    def __key(self):
        return tuple([self.id, self.inchikey, self.mts, self.mtk, self.mtb, self.mtk])

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

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

然而,在创建此类的实例并要求哈希时,我得到以下内容:

>>> met = Metabolite('this_metabolite', '10002', 'AADBRHFDG')
>>> hash(met)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-7941e6f25128> in <module>()
----> 1 hash(met)

classes.py in __hash__(self)
     27 
     28     def __hash__(self):
---> 29         return hash(tuple(self.__key()))
     30 
     31 

TypeError: unhashable type: 'list'

尽管我在类定义中的绝望尝试迫使该类型成为(可散列的)元组。我是Python新手,我们非常感谢任何帮助。

在IDLE中运行时,错误显示为:

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    hash(met)
  File "<string>", line 27, in __hash__
TypeError: unhashable type: 'list'

求助:感谢那些回复的人。

包含空列表的元组不起作用:

>>> my_tuple = tuple(('a',[]))

>>> type(my_tuple)

tuple

>>> hash(my_tuple)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-f63af41cc75b> in <module>()
----> 1 hash(my_tuple)

TypeError: unhashable type: 'list'

所以我必须先创建一个变量列表,然后再将它们放回__key()

def __key(self):
    key_list = []
    key_list.append(self.id)
    key_list.append(self.inchikey)
    key_list.append(self.mts)
    key_list.append(self.mtb)
    for entry in self.mtk:
        key_list.append(entry)
    return tuple(key_list)

1 个答案:

答案 0 :(得分:1)

问题是mtk属性是一个列表(默认情况下)。可变序列类型不能进行哈希处理,因为您的密钥包含mtk(两次),所以密钥不可清除(即使密钥本身是tuple)。

如果您按如下方式修改密钥生成,那么它就变得可以清洗(但可能效率很低):

def __key(self):
    mtk = tuple(self.mtk)
    return tuple([self.id, self.inchikey, self.mts, mtk, self.mtb, mtk])

这将在Python 2.7中返回(通过以上修改从您的问题粘贴的代码):

>>> met = Metabolite('this_metabolite', '10002', 'AADBRHFDG')
>>> hash(met)
7276685348836095537