можно ли использовать экземпляры классов в качестве ключей словаря dict

Могу ли я использовать объект (экземпляр класса) в качестве ключа словаря в Python?

Я хочу использовать экземпляр класса в качестве ключа словаря, например:

Python, похоже, не может обрабатывать классы как ключ словаря, или я ошибаюсь? Кроме того, я мог бы использовать список кортежей, как [(classinstance, helloworld). ] вместо словаря, но это выглядит очень непрофессионально. У вас есть какие-нибудь идеи для решения этой проблемы?

4 ответов

ваши экземпляры должны быть hashable. The словарь python говорит нам:

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

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

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

следующий код работает хорошо, потому что по умолчанию объект класса hashable :

выход : Привет, мир

кроме того, и для более продвинутого использования, вы должны прочитать это сообщение:

попробуйте реализовать хэш и эквалайзер методы в вашем классе.

например, вот простой хэшируемый класс словаря, который я сделал:

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

Источник

Почему я не могу использовать список в качестве ключа dict в Python?

Я немного смущен тем, что можно / нельзя использовать в качестве ключа для Python dict.

У меня было смутное представление о том, что ключ должен быть «хешируемым», но я просто собираюсь признать свое незнание технических деталей; Я не знаю, что здесь происходит на самом деле. Что бы пошло не так, если бы вы попытались использовать списки в качестве ключей, с хешем, скажем, в качестве места в памяти?

Что бы пошло не так, если бы вы попытались использовать списки в качестве ключей, с хешем, скажем, в качестве места в памяти?

Почему я не могу использовать список в качестве ключа dict в Python?

(для всех, кто сталкивается с этим вопросом и ищет способ его обойти)

как объясняют другие здесь, вы действительно не можете. Однако вы можете использовать его строковое представление, если действительно хотите использовать свой список.

Только что обнаружил, что вы можете преобразовать List в кортеж, а затем использовать его в качестве ключей.

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

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

Что бы пошло не так, если бы вы попытались использовать списки в качестве ключей, с хешем, скажем, в качестве места в памяти?

Поиск разных списков с одинаковым содержимым даст разные результаты, даже если сравнение списков с одинаковым содержимым укажет на их эквивалент.

А как насчет использования литерала списка в поиске по словарю?

Читайте также:  можно ли кататься на картинге в городе

Пример 1 : хеширование изменяемого объекта, где хеш-значение основано на изменяемой характеристике объекта.

Некоторые сроки для примера 3

TL; DR: вы можете использовать их в tuple(yourlist) качестве dict ключей, потому что кортежи неизменяемы и хешируются.

Источник

Почему я не могу использовать список как ключ dict в python?

Я немного озадачен тем, что можно / нельзя использовать в качестве ключа для python dict.

У меня было какое-то смутное представление о том, что ключ должен быть «хэшируемым», но я просто собираюсь признать свое собственное незнание технических деталей; Я не знаю, что на самом деле здесь происходит. Что может пойти не так, если вы попытаетесь использовать списки в качестве ключей с хешем, скажем, как место их памяти?

8 ответов

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

Что может пойти не так, если вы попытаетесь использовать списки в качестве ключей с хешем, скажем, как место их памяти?

Только что вы можете изменить список в кортеж, а затем использовать его в качестве ключей.

Ваш ответ можно найти здесь:

Почему списки не могут быть словарями

Пример 1 : хэширование изменяемого объекта, где значение хеш-функции основано на изменяемой характеристике объекта.

Некоторые временные характеристики для примера 3

TL ; DR: вы можете использовать tuple(yourlist) в качестве dict ключей, потому что кортежи являются неизменяемыми и хешируемыми.

Что может пойти не так, если вы попытаетесь использовать списки в качестве ключей с хешем, скажем, как место их памяти?

Поиск разных списков с одинаковым содержимым приведет к разным результатам, даже если сравнение списков с одинаковым содержимым покажет их как эквивалентные.

Как насчет использования литерала списка в поиске по словарю?

Согласно документации Python 2.7.2:

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

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

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

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

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

Источник

Почему я не могу использовать список в качестве ключа dict в python?

Я немного смущен тем, что может/не может использоваться в качестве ключа для питона-диктата.

Итак, кортеж является неизменным типом, но если я скрою его внутри, то он не может быть ключом. Не мог бы я просто скрыть список внутри модуля?

У меня была какая-то неопределенная идея, что ключ должен быть “хэшируемым”, но я просто буду признавать свое невежество в отношении технических деталей; Я не знаю, что здесь происходит. Что пойдет не так, если вы попытаетесь использовать списки в качестве ключей, а хэш как, скажем, их ячейку памяти?

Читайте также:  можно ли мазать герпес тетрациклиновой мазью

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

Что пойдет не так, если вы попытаетесь использовать списки в качестве ключей, а хэш как, скажем, их ячейку памяти?

Почему я не могу использовать список в качестве ключа dict в python?

(для любого, кто спотыкается на этот вопрос, ищет способ обойти его)

как объясняют другие здесь, действительно, вы не можете. Однако вы можете использовать его строковое представление, если вы действительно хотите использовать свой список.

Проблема в том, что кортежи неизменяемы, а списки – нет. Рассмотрим следующее

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

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

Что пойдет не так, если вы попытаетесь использовать списки в качестве ключей, а хэш как, скажем, их ячейку памяти?

Поиск разных списков с одним и тем же содержимым приведет к различным результатам, хотя сравнение списков с одним и тем же содержимым означает их эквивалент.

Как использовать литерал списка в поиске словаря?

Только что вы можете изменить список в кортеж, а затем использовать его в качестве ключей.

Ваш тент можно найти здесь:

Почему списки не могут быть ключами для слова

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

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

В качестве примечания, фактическая реализация поиска диктобъектов основана на алгоритме D от Knuth Vol. 3, гл. 6.4. Если вам доступна эта книга, ее стоит прочитать, кроме того, если вы действительно, действительно заинтересованы, вы можете взглянуть на комментарии разработчиков по фактической реализации dictobject здесь. В нем подробно рассказывается, как именно это работает. Существует также лекция по питону о реализации словарей, которые могут вас заинтересовать. Они проходят определение ключа и что такое хеш в первые несколько минут.

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

Пример 1: хэширование изменяемого объекта, где значение хеш-функции основано на изменяемой характеристике объекта.

Пример 2 :… но почему не просто постоянное хеш-значение?

Читайте также:  мышечные волокна без исчерченности в кале у взрослого что это значит в большом количестве

Пример 3 :… хорошо, как насчет постоянных хэшей во всех случаях?!

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

Для нахождения нужного экземпляра с помощью my_dictможно ли использовать экземпляры классов в качестве ключей словаря dict или key in my_dict (или item in my_set ) необходимо выполнить столько проверок на равенство, сколько существует примеров stupidlist3 в ключах dict (в худшем случае). На данный момент цель словаря – поиск O (1) – полностью побеждена. Это продемонстрировано в следующих случаях (сделано с IPython).

Некоторые сроки для примера 3

Согласно документации Python 2.7.2:

Объект hashable, если он имеет значение хеша, которое никогда не изменяется в течение его жизненного цикла (ему нужен метод хеширования()) и может быть по сравнению с другими объектами (для этого требуется eq() или cmp()). Объекты Hashable, которые сравниваются равными, должны иметь одно и то же значение хэш-функции.

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

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

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

Использование id для хешей списка будет означать, что все списки сравниваются по-разному, что было бы удивительно и неудобно.

Источник

Могу ли я использовать объект (экземпляр класса) в качестве ключа словаря в Python?

Я хочу использовать экземпляр класса в качестве ключа словаря, например:

Python, кажется, не может обрабатывать классы как ключ словаря, или я ошибаюсь? Кроме того, я мог бы использовать список кортежей, например [(classinstance, helloworld). ] вместо словаря, но это выглядит очень непрофессионально. У вас есть какие-нибудь подсказки для решения этой проблемы?

4 ответов:

Экземпляры должны быть hashable. Глоссарий python говорит нам:

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

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

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

Следующий код работает хорошо, потому что по умолчанию объект класса хешируется :

Выход : Привет Мир

В дополнение и для более продвинутого использования, вы должны прочитать этот пост:

Попробуйте реализовать методы hash и eq в своем классе.

Например, вот простой хэшируемый класс словаря, который я сделал:

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

Источник

Строй-портал