Ви намагаєтесь використовувати dictключ як ключ до іншого dictчи в а set. Це не працює, тому що ключі повинні бути хешированными. Як правило, підлягають переміненню лише незмінні об'єкти (рядки, цілі числа, поплавці, фрозенсети, кортежі незмінних) (хоча можливі винятки). Отже, це не працює:
>>> dict_key = {"a": "b"}
>>> some_dict[dict_key] = True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
Щоб використовувати дикт як ключ, вам потрібно перетворити його на щось, що може бути спокійно спершу. Якщо диктант, який ви хочете використовувати в якості ключа, складається лише з незмінних значень, ви можете створити його хешируемое представлення так:
>>> key = frozenset(dict_key.items())
Тепер ви можете використовувати keyяк ключ у dictабо set:
>>> some_dict[key] = True
>>> some_dict
{frozenset([('a', 'b')]): True}
Звичайно, вам потрібно повторювати вправу, коли ви хочете щось шукати за допомогою дикта:
>>> some_dict[dict_key] # Doesn't work
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> some_dict[frozenset(dict_key.items())] # Works
True
Якщо dictви хочете використовувати в якості ключа значення, які самі є диктами та / або списками, вам потрібно рекурсивно "заморожувати" потенційний ключ. Ось відправна точка:
def freeze(d):
if isinstance(d, dict):
return frozenset((key, freeze(value)) for key, value in d.items())
elif isinstance(d, list):
return tuple(freeze(value) for value in d)
return d