我可以在Python中使用对象(类的实例)作为字典键吗?

时间:2011-09-26 19:22:45

标签: python list dictionary tuples

我想将类实例用作字典键,例如:

classinstance = class()
dictionary[classinstance] = 'hello world'

Python似乎无法将类作为字典键处理,或者我错了? 另外,我可以使用像[(classinstance,helloworld),...]这样的元组列表而不是字典,但这看起来非常不专业。 你有解决这个问题的线索吗?

4 个答案:

答案 0 :(得分:11)

您的实例需要可以播放。 python glossary告诉我们:

  

如果对象具有在其生命周期内永远不会更改的哈希值(它需要__hash__()方法),并且可以与其他对象进行比较(它需要__eq__()或{{ 1}}方法)。比较相等的Hashable对象必须具有相同的哈希值。

     

Hashability使对象可用作字典键和set成员,因为这些数据结构在内部使用哈希值。

     

所有Python的不可变内置对象都是可清除的,而没有可变容器(例如列表或字典)。默认情况下,作为用户定义类实例的对象是可清除的;它们都比较不相等,它们的哈希值是它们的id()。

答案 1 :(得分:5)

以下代码运行良好,因为默认情况下,您的类对象是可清除的:

Class Foo(object):
    def __init__(self):
        pass

myinstance = Foo()
mydict = {myinstance : 'Hello world'}

print mydict[myinstance]

输出: 你好世界

此外,为了更高级的用法,您应该阅读这篇文章:

Object of custom type as dictionary key

答案 2 :(得分:5)

尝试在班级中实施哈希 eq 方法。

例如,这是一个简单的可编辑字典类:

class hashable_dict:
    def __init__(self, d):
        self.my_dict = d
        self.my_frozenset = frozenset(d.items())
    def __getitem__(self, item):
        return self.my_dict[item]
    def __hash__(self):
        return hash(self.my_frozenset)
    def __eq__(self, rhs):
        return isinstance(rhs, hashable_dict) and self.my_frozenset == rhs.my_frozenset
    def __ne__(self, rhs):
       return not self == rhs
    def __str__(self):
        return 'hashable_dict(' + str(self.my_dict) + ')'
    def __repr__(self):
        return self.__str__()

答案 3 :(得分:3)

将实例用作字典键没有任何问题,只要它跟在the rules之后:字典键必须是不可变的。