Я имею в виду, почему мы не можем поставить ключ dict в качестве dict?
это означает, что мы не можем иметь словарь, имеющий ключ в качестве другого словаря...
Я имею в виду, почему мы не можем поставить ключ dict в качестве dict?
это означает, что мы не можем иметь словарь, имеющий ключ в качестве другого словаря...
Короткий ответ: поскольку они являются изменяемыми контейнерами.
Если dict был хэширован, его хэш изменился бы при изменении его содержимого.
С этим легко справиться. Оберните диктофон в frozenset, прежде чем вы его сделаете. Затем, когда вам нужно использовать его, преобразуйте его обратно в dict.
>>> unhashable = {'b': 'a', 'a': 'b'}
>>> hashable = frozenset(unhashable.items())
>>> unhashable = dict(hashable)
>>> unhashable
{'a': 'b', 'b': 'a'}
Обратите внимание, что порядок словарных букв undefined в любом случае, поэтому изменение порядка клавиш не имеет значения.
Как говорили другие, хеш-значение 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 с адресом объекта в памяти.
Ни один из изменяемых типов контейнеров в Python не является hashable, поскольку они изменяемы и, следовательно, их хэш-значение может меняться в течение их жизни.
Возможно, неправильные причины я столкнулся с этой проблемой несколько раз; где я хочу указать полный 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'}
Легко манипулировать, так как это просто строка. И его можно де-сериализовать в объект, если вы хотите ссылаться на его члены.