目录
1. TypeError: unhashable type: 'list'
2. 何为哈希?
2.1 哈希
2.2 哈希表
2.3 Python中的哈希表的例子
3. Why list is unhashable?
1. TypeError: unhashable type: 'list'
这个错误通常意味着你试图将一个list对象用作哈希参数(hash argument),有以下两种典型(常见)的情况:
(1) 用作字典的键值
(2) 用作集合set的元素
myDict = {[1,2,3]:'123', 'name':'chenxy'}
mySet = set()
mySet.add([1,2,3])
以上两个例子都将导致如题的错误。
原因是list是不能用作哈希值的(can't be hashed),通常的解决方案是将list转换为tuple再使用,如下例所示:
myDict = {tuple([1,2,3]):'123', 'name':'chenxy'}
mySet = set()
mySet.add(tuple([1,2,3]))
print(myDict)
print(mySet)
运行结果如下:
{(1, 2, 3): '123', 'name': 'chenxy'}
{(1, 2, 3)}
2. 何为哈希?
2.1 哈希
哈希(hash)也成为散列,是计算机科学中的一个概念,它是指把任意长度的输入,通过哈希算法变换成固定长度的输出,这个输出值就是哈希(散列)值。实现这一算法的函数就叫做哈希函数,哈希算法最重要的特点就是:
- 相同的输入一定得到相同的输出;
- 不同的输入大概率得到不同的输出。
哈希函数就是实现了哈希算法的函数,将输入参数变换为一个唯一的(固定长度的)数,它可以接收任意一经初始化后就不会再变化的对象(从哈希函数来看就是一个长度不一的二进制字符串)作为参数,这一特性通常被用于生成字典的键。有很多种哈希算法,这里就不一一介绍。
python的内置函数hash()用于将输入参数变换为其对应的哈希值,比如说:
hash(tuple([1,2,3]))
Out[93]: 529344067295497451
2.2 哈希表
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而进行随机访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数就是哈希函数,存放记录的数组叫做散列表。
2.3 Python中的哈希表的例子
python中的dict就是哈希表的一种实现。python中的set也是哈希表的一种实现。dict的元素是{key: value}对,而set可以看作是只有key而没有value。dict中key必须保持唯一性,否则的话就无法实现正确查询。set则由其定义可知其中的元素都是唯一(unique)的。因此两者都以哈希表的方式来实现也就不足为怪。
3. Why list is unhashable?
哈希表要求用同一对象作为key查询得到的结果保持不变(否则的话,每次查询相同的key,返回的值都不同就无法起到数据存储的功能了),这就要求用作key的对象本身必须是保持不变的(immutable once it is initialized)。如果一个对象是可变的,那它的内容一旦发生变化,它的二进制表示就会发生变化,以它为输入经由哈希函数计算出来的哈希值也就发生变化了,因此以它为键值进行查询而得到的结果也就与上次查询结果不一样。
list是mutable类型,tuple是immutable类型,因此list是unhashable的,不能用作dict的键,也不能作为set的元素,而tuple就可以。
Python中的hashable objects的例子:
int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
Python中的unhashable objects的例子:
list, dict, set, bytearray, user-defined classes
Reference:
[1] http://net-informations.com/python/iq/unhashable.htmhttp://net-informations.com/python/iq/unhashable.htm