询问 Python 值“是否可散列”

问题描述 投票:0回答:4

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

我想做的一个改变是交换键和值。不幸的是,有些价值观本身就是命令。但是,这会生成“不可散列类型:'dict'”错误。我真的不介意将值字符串化并为其提供密钥。但是,我希望能够做这样的事情:

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

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

python hash
4个回答
83
投票

Python 3.x

使用

collections.abc.Hashable
typing.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
)。


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

4
投票

Python 中所有内置的可哈希对象都有一个

.__hash__()
方法。你可以检查一下。

olddict = {"a":1, "b":{"test":"dict"}, "c":"string", "d":["list"] }

for key in olddict:
   if(olddict[key].__hash__):
      print str(olddict[key]) + " is hashable"
   else: 
      print str(olddict[key]) + " is NOT hashable"

输出

1 is hashable
string is hashable
{'test': 'dict'} is NOT hashable
['list'] is NOT hashable

2
投票

为什么不使用鸭子打字?

for key in olddict:
   try:
       newdict[olddict[key]] = key
   except TypeError:
       newdict[str(olddict[key])] = key
© www.soinside.com 2019 - 2024. All rights reserved.