使用不可清除的Python对象作为词典中的键

Cas*_*ash 4 python

Python不允许将不可清除的对象用作其他字典中的键.正如Andrey Vlasovskikh所指出的,对于使用非嵌套字典作为键的特殊情况,有一个很好的解决方法:

frozenset(a.items())#Can be put in the dictionary instead
Run Code Online (Sandbox Code Playgroud)

有没有使用任意对象作为词典中的键的方法?

示例:

如何将其用作钥匙?

{"a":1, "b":{"c":10}}
Run Code Online (Sandbox Code Playgroud)

您实际上必须在代码中使用类似的东西是非常罕见的.如果您认为是这种情况,请考虑先更改数据模型.

确切的用例

用例是缓存对任意关键字唯一函数的调用.字典中的每个键都是一个字符串(参数的名称),对象可能非常复杂,包括分层的字典,列表,元组等.

相关问题

这个子问题已从这里的问题中分离出来.这里的解决方案处理字典没有分层的情况.

Len*_*bro 7

别.我同意Andreys对前一个问题的评论,即将字典作为键,而不是嵌套字典是没有意义的.您的数据模型显然非常复杂,字典可能不是正确的答案.你应该尝试一些OO.

  • +1因为这可能是最终的. (2认同)
  • 我不同意它应该是一个评论.在我看来,这是正确的答案.YMMV当然. (2认同)
  • +1:不要.如果你认为你需要这个,那么你的"嵌套字典"不应该是一个嵌套字典 - 它应该是一个正确的类,具有正确的`__hash__`方法.不要编写代码来处理"任意"结构.编写适当的类而不是"任意"结构. (2认同)

fly*_*dor 7

基于Chris Lutz的解决方案.

import collections

def hashable(obj):
    if isinstance(obj, collections.Hashable):
        items = obj
    elif isinstance(obj, collections.Mapping):
        items = frozenset((k, hashable(v)) for k, v in obj.iteritems())
    elif isinstance(obj, collections.Iterable):
        items = tuple(hashable(item) for item in obj)
    else:
        raise TypeError(type(obj))

    return items
Run Code Online (Sandbox Code Playgroud)