0

ここで提案されているハッシュ定義を実装しようとしていますが、クラスでハッシュを使用しようとするとエラーが発生します。クラスは次のように定義されています。

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

1 に答える 1

1

問題は、mtk属性が (デフォルトで) リストであることです。変更可能なシーケンス型はハッシュできず、キーにmtk(2 回) が含まれているため、キーはハッシュ可能ではありません (キー自体が a であっても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
于 2013-01-30T01:32:57.990 に答える