为什么在Python中,集合(set)、字典(dict)、列表(list)是不可哈希的?

4
“unhashable”指的是无法进行哈希(hash)运算的对象。
>>> a={1,2,3}
>>> b={4,5,6}
>>> set([a,b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>>

有人可以告诉我这个错误到底是什么吗?还有,我能在Python中将一个集合添加到另一个集合中吗?


1
可哈希类型具有在其生命周期内保证为常量的哈希值。如果两个对象比较 eq(),则它们必须具有相同的哈希值。这些条件对于可变对象(集合、列表、字典等)是一个问题,因为随着对象的更改,相等性也会发生变化。不可变类型(字符串、元组等)没有这个问题,因为它们无法更改。不可变类型是可哈希的,而可变类型则不是。 - AChampion
3个回答

3
正如Kasramvd所解释的那样,Python中的可变对象并实现__eq__函数的对象是不可哈希的。
由于集合、列表和字典都是可变的(即它们可以被更改;例如,您可以向它们中的所有项添加、删除项),因此它们不能被哈希。
由于集合的集合是不可能的,也许元组的集合可能会起作用,尽管您需要进行额外的簿记(例如确保唯一值)才能实现您所描述的确切内容。
a = (1,2,3)
b = (4,5,6)
c = set([a,b])

甚至更好的是,一组frozensets。类似于集合,但不可变(您无法向其中添加或删除元素)。
a = frozenset(a)
b = frozenset(b)
c = set([a,b])

2
但是frozenset的集合是。 - Dan D.

3

没有__hash__()属性的对象被称为unhashable。Python文档已经很好地解释了原因:

如果一个类定义了可变对象并实现了__eq__()方法,则不应该实现__hash__(),因为可哈希集合的实现要求键的哈希值是不可变的(如果对象的哈希值发生更改,则它将在错误的哈希桶中)。


0
哈希函数是一种将任意大小的数据映射到固定大小数据的函数。哈希函数返回的值称为哈希值、哈希码、哈希和或简单地称为哈希。
Python中的字典就是一个哈希表。
集合只能包含字符串、字符或数字,而不能包含字典或其他集合。你可能需要查看:https://docs.python.org/2/tutorial/datastructures.html#sets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接