почему объекты dict не доступны в python? - PullRequest
24 голосов
/ 24 декабря 2009

Я имею в виду, почему мы не можем поставить ключ dict как dict?

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

Ответы [ 5 ]

38 голосов
/ 24 декабря 2009

Краткий ответ: потому что они изменяемые контейнеры .

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

14 голосов
/ 03 января 2012

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

>>> unhashable = {'b': 'a', 'a': 'b'}
>>> hashable = frozenset(unhashable.items())
>>> unhashable = dict(hashable)
>>> unhashable
{'a': 'b', 'b': 'a'}

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

6 голосов
/ 24 декабря 2009

Как уже говорили другие, значение хеша dict изменяется при изменении содержимого.

Однако, если вам действительно нужно использовать dicts в качестве ключей, вы можете создать подкласс dict для создания версии, которую можно хэшировать.

>>> class hashabledict(dict):
...    def __hash__(self):
...        return id(self)
... 
>>> hd = hashabledict()
>>> d = dict()
>>> d[hd] = "foo"
>>> d
{{}: 'foo'}

>>> hd["hello"] = "world"
>>> d
{{'hello': 'world'}: 'foo'}

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

1 голос
/ 14 августа 2015

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

Самый простой способ сделать неизменным и быстро используемым dict в качестве значения ключа - сделать его JSON (или сериализовать в вашей любимой альтернативе).

Например:

>>> import json
>>> d = {'hey':1, 'there':2}
>>> d_key = json.dumps(d)
>>> d_key
'{"there": 2, "hey": 1}'
>>> d2 = {d_key: 'crazytown'}
>>> d2
{'{"there": 2, "hey": 1}': 'crazytown'}

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

1 голос
/ 24 декабря 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...