Вопрос-Ответ

What does "hashable" mean in Python?

Что означает "hashable" в Python?

Что именно означает утверждение, что объект в коде Python является хэшируемым?

Переведено автоматически
Ответ 1

Из глоссария Python:


Объект является хэшируемым, если у него есть хэш-значение, которое никогда не меняется в течение его срока службы (для этого нужен __hash__() метод), и его можно сравнить с другими объектами (для этого нужен метод __eq__() or __cmp__()). Хэшируемые объекты, которые сравниваются равными, должны иметь одинаковое хэш-значение.


Хэшируемость делает объект пригодным для использования в качестве ключа словаря и элемента набора, потому что эти структуры данных используют значение хэша внутри.


Все неизменяемые встроенные объекты Python являются хэшируемыми, в то время как изменяемые контейнеры (такие как списки или словари) отсутствуют. Объекты, являющиеся экземплярами пользовательских классов, хэшируются по умолчанию; все они сравниваются неравнозначно, и их хэш-значение равно их id().


Ответ 2

Во всех приведенных здесь ответах содержится хорошее рабочее объяснение хэшируемых объектов в python, но я считаю, что сначала нужно понять термин "хэширование".

Хеширование - это концепция в информатике, которая используется для создания высокопроизводительных структур данных с псевдослучайным доступом, в которых необходимо хранить большой объем данных и быстро получать к нему доступ.

Например, если у вас есть 10 000 телефонных номеров, и вы хотите сохранить их в массиве (который представляет собой последовательную структуру данных, которая хранит данные в смежных ячейках памяти и обеспечивает произвольный доступ), но у вас может не быть требуемого количества смежных ячеек памяти.

Итак, вы можете вместо этого использовать массив размером 100 и использовать хэш-функцию для сопоставления набора значений с теми же индексами, и эти значения могут храниться в связанном списке. Это обеспечивает производительность, аналогичную производительности массива.

Теперь хэш-функция может быть такой же простой, как деление числа на размер массива и использование остатка в качестве индекса.

Для получения более подробной информации обратитесь к https://en.wikipedia.org/wiki/Hash_function

Вот еще одна хорошая ссылка: http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html

Ответ 3

Все, что не изменяемо (изменяемый означает, с вероятностью измениться), может быть хэшировано. Помимо хэш-функции, которую нужно искать, если она есть в классе, например. dir(tuple) и в поисках __hash__ метода, вот несколько примеров

#x = hash(set([1,2])) #set unhashable
x = hash(frozenset([1,2])) #hashable
#x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable
x = hash((1,2,3)) #tuple of immutable objects, hashable
#x = hash()
#x = hash({1,2}) #list of mutable objects, unhashable
#x = hash([1,2,3]) #list of immutable objects, unhashable

Список неизменяемых типов:

int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes

Список изменяемых типов:

list, dict, set, bytearray, user-defined classes
Ответ 4

В моем понимании, согласно глоссарию Python, когда вы создаете экземпляр объектов, которые являются хэшируемыми, неизменяемое значение также вычисляется в соответствии с элементами или значениями экземпляра. Например, это значение затем может быть использовано в качестве ключа в словаре, как показано ниже:

>>> tuple_a = (1, 2, 3)
>>> tuple_a.__hash__()
2528502973977326415
>>> tuple_b = (2, 3, 4)
>>> tuple_b.__hash__()
3789705017596477050
>>> tuple_c = (1, 2, 3)
>>> tuple_c.__hash__()
2528502973977326415
>>> id(tuple_a) == id(tuple_c) # tuple_a and tuple_c same object?
False
>>> tuple_a.__hash__() == tuple_c.__hash__() # hash of tuple_a and tuple_c same value?
True
>>> dict_a = {}
>>> dict_a[tuple_a] = 'hiahia'
>>> dict_a[tuple_c]
'hiahia'

Мы можем обнаружить, что хэш-значение tuple_a и tuple_c одинаковы, поскольку у них одинаковые члены.
Когда мы используем tuple_a в качестве ключа в dict_a, мы можем обнаружить, что значение для dict_a[tuple_c] такое же, что означает, что когда они используются в качестве ключа в словаре, они возвращают одно и то же значение, потому что значения хэша одинаковы.
Для тех объектов, которые не являются хэшируемыми, метод __hash__ определяется как None:

>>> type(dict.__hash__) 
<class 'NoneType'>

Я предполагаю, что это хэш-значение вычисляется при инициализации экземпляра, а не динамическим способом, поэтому хэшируемыми являются только неизменяемые объекты. Надеюсь, это поможет.

2023-12-16 23:50 python