Могу ли я использовать объект (экземпляр класса) в качестве ключа словаря в Python?
Я хочу использовать экземпляр класса в качестве ключа словаря, например:
classinstance = class()
dictionary[classinstance] = 'hello world'
Python, кажется, не может обрабатывать классы как ключ словаря, или я ошибаюсь?
Кроме того, я мог бы использовать список кортежей, например [(classinstance, helloworld),...] вместо словаря, но это выглядит очень непрофессионально.
У вас есть какие-нибудь подсказки для решения этой проблемы?
4 ответов:
Экземпляры должны быть hashable. Глоссарий python говорит нам:
Объект является хэшируемым, если он имеет хэш-значение, которое никогда не изменяется в течение его жизни (ему нужен метод__hash__()), и может быть сравнен с другими объектами (ему нужен метод__eq__()или__cmp__()). Хэшируемые объекты, которые сравниваются равными, должны иметь одинаковое хэш-значение.Хэшируемость позволяет использовать объект в качестве ключа словаря и элемента набора, поскольку эти структуры данных используют хэш-значение внутренне.
Все неизменяемые встроенные объекты Python являются хэшируемыми, в то время как никакие изменяемые контейнеры (такие как списки или словари) ими не являются. Объекты, являющиеся экземплярами пользовательских классов, по умолчанию хэшируются; все они сравниваются неравномерно, и их хэш-значением является их id().
Следующий код работает хорошо, потому что по умолчанию объект класса хешируется :
Class Foo(object): def __init__(self): pass myinstance = Foo() mydict = {myinstance : 'Hello world'} print mydict[myinstance]Выход : Привет Мир
В дополнение и для более продвинутого использования, вы должны прочитать этот пост:
Попробуйте реализовать методы hash и 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__()
Нет ничего плохого в использовании экземпляра в качестве ключа словаря, если он следует правилам: ключ словаря должен быть неизменяемым.
Comments