Hashable, неизменный

От недавнего, ТАКИМ ОБРАЗОМ, вопрос (см., Создает словарь в Python, который индексируется списками), я понял, что у меня, вероятно, была неправильная концепция значения hashable и неизменных объектов в Python.

  • Что делает hashable средний на практике?
  • Каково отношение между hashable и неизменным?
  • Есть ли изменяемые объекты, которые являются hashable или неизменными объектами, которые не hashable?

76
задан Community 23 May 2017 в 12:03
поделиться

5 ответов

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

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

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

Чтобы по-настоящему понять идею, вам следует попробовать реализовать свою собственную хеш-таблицу на таком языке, как C / C ++, или прочитать Java-реализацию класса HashMap .

84
ответ дан 24 November 2019 в 11:20
поделиться

Технически хеширование означает, что класс определяет __ hash __ () . Согласно документации:

__ hash __ () должен возвращать целое число. Единственное обязательное свойство - это то, что сравниваемые одинаковые объекты имеют одинаковое хеш-значение; рекомендуется как-то смешивать (например, с использованием исключающего ИЛИ) хеш-значения для компонентов объекта, которые также играют роль в сравнении объектов.

Я думаю, что для встроенных типов Python все хешируемые типы также неизменяемы.

Было бы сложно, но возможно, возможно, иметь изменяемый объект, который, тем не менее, определял бы __ hash __ () .

8
ответ дан 24 November 2019 в 11:20
поделиться

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

Объект является хешируемым если у него есть хеш-значение, которое никогда не меняется в течение его времени существования (ему нужен метод __ hash __ () ), и его можно сравнивать с другими объектами (ему нужен __ eq __ () или __ cmp __ () метод). Хэшируемые объекты, которые сравнивают равные, должны иметь одинаковое хеш-значение.

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

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

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

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

7
ответ дан 24 November 2019 в 11:20
поделиться

Hashable означает, что значение переменной может быть представлено (или, скорее, закодировано) константой - строка, число и т. д. То, что может быть изменено (изменяемое), не может быть представлено чем-то, чего нет. Следовательно, любая изменяемая переменная не может быть хэшируемой, и, по тому же признаку, хешируемыми могут быть только неизменяемые переменные.

Надеюсь, это поможет ...

0
ответ дан 24 November 2019 в 11:20
поделиться

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

В других языках хэш-значение больше связано с "идентичностью" объекта, а не (обязательно) с его значением. Таким образом, для изменяемого объекта указатель может быть использован для начала хэширования. Предполагая, конечно, что объект не перемещается в памяти (как это делают некоторые GC). Такой подход используется, например, в Lua. Это позволяет использовать изменяемый объект в качестве ключа таблицы, но создает несколько (неприятных) сюрпризов для новичков.

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

1
ответ дан 24 November 2019 в 11:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: