Вы пытаетесь использовать 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}
Конечно, вам нужно повторять упражнение всякий раз, когда вы хотите найти что-то, используя dict:
>>> 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