Você está tentando usar um dict
como uma chave para outro dict
ou em um set
. Isso não funciona porque as chaves precisam ser laváveis. Como regra geral, apenas objetos imutáveis (seqüências de caracteres, números inteiros, flutuadores, conjuntos de propriedades, tuplas de imutáveis) são laváveis (embora sejam possíveis exceções). Portanto, isso não funciona:
>>> dict_key = {"a": "b"}
>>> some_dict[dict_key] = True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
Para usar um ditado como chave, você precisa transformá-lo em algo que pode ser primeiro misturado. Se o ditado que você deseja usar como chave consistir apenas em valores imutáveis, você poderá criar uma representação hashável assim:
>>> key = frozenset(dict_key.items())
Agora você pode usar key
como chave em um dict
ou set
:
>>> some_dict[key] = True
>>> some_dict
{frozenset([('a', 'b')]): True}
Claro que você precisa repetir o exercício sempre que quiser procurar algo usando um ditado:
>>> 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
Se dict
você deseja usar como chave possui valores que são dictos e / ou listas, é necessário "congelar" recursivamente a chave em potencial. Aqui está um ponto de partida:
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