Python异常:unhashable type 是怎么回事?

1异常

小伙伴们,平时遇到过下面这个 TypeError 异常吗?

 
   
  1. In [1]: a = [1,2]


  2. In [2]: di = {a:'unhashable value as key'}

  3. ---------------------------------------------------------------------------

  4. TypeError Traceback (most recent call last)

  5. 2-6f10e8ebb153> in

  6. ----> 1 di = {a:'unhashable value as key'}


  7. TypeError: unhashable type: 'list'


这个 TypeError 翻译过来---类型错误:不可哈希的类型:'list'


2原因

既然有不可哈希(unhashable),就会有可哈希(hashable)类型。那么,什么类型为可哈希? 引用 Python3 官方解释:

一个对象的哈希值如果在其生命周期内绝不改变,就被称为 可哈希 (它需要具有 hash() 方法),并可以同其他对象进行比较(它需要具有 eq() 方法)。可哈希对象必须具有相同的哈希值比较结果才会相同。

一个对象的哈希值在生命周期内不改变,就被成为 可哈希。可哈希性使得对象能够作为字典键或集合成员使用,因为这些数据结构要在内部使用哈希值。


可变容器(例如列表或字典)都不可哈希。所以,回过头来看文章开头的 TypeError ,就容易解释了,只有可哈希对象才能作为字典的键。


同样,文章开头的列表 a ,也不能作为集合成员使用,否则,也会抛出同样的异常,如下所示:

 
   
  1. In [3]: myset = {a,1,2}

  2. ---------------------------------------------------------------------------

  3. TypeError Traceback (most recent call last)

  4. 3-fac576c0e64f> in

  5. ----> 1 myset = {a,1,2}


  6. TypeError: unhashable type: 'list'


3评价哈希值

如何评判一个对象的哈希值是否改变呢?一般地,

1、所有 Python 中的不可变内置对象都是可哈希的;

2、可变容器(例如列表或字典)都不可哈希。

3、用户定义类的实例对象默认是可哈希的。

4计算哈希值

Python 中的 hash 函数用来计算对象的哈希值。相等的两个对象一定拥有相等的哈希值,反过来却不成立。

 
   
  1. hash(obj, /)

  2. Return the hash value for the given object.


  3. Two objects that compare equal must also have the same hash value, but the

  4. reverse is not necessarily true.


相等的对象 mys 和 comb 必然具有相等的哈希值,如下所示:

 
   
  1. In [19]: mys = 'abc'


  2. In [20]: hash(mys)

  3. Out[20]: 4999899737522052207


  4. In [21]: comb = 'a'+'bc'


  5. In [22]: hash(comb)

  6. Out[22]: 4999899737522052207


而不可哈希的对象,是没有哈希值的,比如字典 di. 原因是set()和dict()使用对象的hash 值作为内部索引,以便能快速索引到指定对象。因此,作为字典键的类型,必须为可哈希的,并且可哈希的对象必须确保每次返回相同的 hash 值,这样才能确保字典的正常工作。


 
   
  1. In [57]: di={}


  2. In [58]: hash(di)

  3. ---------------------------------------------------------------------------

  4. TypeError Traceback (most recent call last)

  5. 58-4ca9267f2fa5> in

  6. ----> 1 hash(di)


  7. TypeError: unhashable type: 'dict'


总结

1、大家首先要知道:抛出对象不可哈希的类型这个异常时,是怎么回事

2、字典和集合的键类型必须为可哈希的

3、可哈希对象的属性值一定是不能被修改的,如果自己定义的可哈希对象,随意修改属性值,会发生不可预见的行为。



今天教程又添加新的内容,欢迎围观:

「送36个:Python 数据分析必备学习路线」


640?wx_fmt=jpeg

Python与机器学习算法频道

长按订阅,干货满满


你可能感兴趣的:(Python异常:unhashable type 是怎么回事?)