Próbujesz użyć a dictjako klucza do innego dictlub w set. To nie działa, ponieważ klucze muszą być hashowane. Zasadniczo tylko niezmienne obiekty (ciągi znaków, liczby całkowite, zmiennoprzecinkowe, zestawy zamrożone, krotki elementów niezmiennych) są hashowane (choć możliwe są wyjątki). Więc to nie działa:
>>> dict_key = {"a": "b"}
>>> some_dict[dict_key] = True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
Aby użyć dykta jako klucza, musisz przekształcić go w coś, co może być najpierw zaszyfrowane. Jeśli dykt, którego chcesz użyć jako klucza, składa się tylko z niezmiennych wartości, możesz utworzyć jego haszowalną reprezentację w następujący sposób:
>>> key = frozenset(dict_key.items())
Teraz możesz użyć keyjako klucza w a dictlub set:
>>> some_dict[key] = True
>>> some_dict
{frozenset([('a', 'b')]): True}
Oczywiście musisz powtórzyć ćwiczenie, gdy chcesz coś sprawdzić za pomocą dykta:
>>> 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
Jeśli dictklucz, którego chcesz użyć jako klucza, ma wartości, które same są dyktami i / lub listami, musisz rekurencyjnie „zamrozić” przyszły klucz. Oto punkt wyjścia:
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