询问关于 Python 值的“可哈希”

新手上路,请多包涵

我有兴趣采用任意指令并将其复制到新指令中,并在此过程中对其进行变异。

我想做的一种改变是交换键和值。不幸的是,有些值本身就是命令。但是,这会生成“不可散列类型:‘dict’”错误。我真的不介意将值字符串化并给它键。但是,我希望能够做这样的事情:

 for key in olddict:
  if hashable(olddict[key]):
    newdict[olddict[key]] = key
  else
    newdict[str(olddict[key])] = key

有没有一种干净的方法可以做到这一点, 而不 涉及捕获异常和解析消息字符串以获取“不可散列类型”?

原文由 Paul Nathan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 410
2 个回答

Python 3.x

使用 collections.abc.Hashabletyping.Hashable

 >>> import typing
>>> isinstance({}, typing.Hashable)
False
>>> isinstance(0, typing.Hashable)
True

注:两者是同一个,后者只是前者的别名。另请注意 collections.Hashable 已在 Python 3.10+ 中删除(自 3.7 起已弃用)。

Python 2.6+(原始答案)

从 Python 2.6 开始,您可以使用抽象基类 collections.Hashable

 >>> import collections
>>> isinstance({}, collections.Hashable)
False
>>> isinstance(0, collections.Hashable)
True

__hash__ 的文档中也简要提到了这种方法。

这样做意味着当程序试图检索它们的哈希值时,不仅类的实例会引发一个适当的 TypeError ,而且在检查时它们也会被正确识别为不可哈希 isinstance(obj, collections.Hashable) (不像定义自己的类 __hash__() 显式引发 TypeError )。

原文由 Mark Byers 发布,翻译遵循 CC BY-SA 4.0 许可协议

def hashable(v):
    """Determine whether `v` can be hashed."""
    try:
        hash(v)
    except TypeError:
        return False
    return True

原文由 Ned Batchelder 发布,翻译遵循 CC BY-SA 2.5 许可协议

推荐问题