理解Python集合的行为
内置类型 set
的文档中说:
class set([iterable])
返回一个新的集合(set)或不可变集合(frozenset)对象,这个对象的元素来自可迭代的对象。集合的元素必须是可哈希的。
这没问题,但为什么这个代码可以运行:
>>> l = range(10)
>>> s = set(l)
>>> s
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
而这个却不行:
>>> s.add([10])
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
s.add([10])
TypeError: unhashable type: 'list'
这两个都是列表。在初始化的时候是不是发生了什么魔法?
6 个回答
5
In [13]: (2).__hash__
Out[13]: <method-wrapper '__hash__' of int object at 0x9f61d84>
In [14]: ([2]).__hash__ # nothing.
问题在于,set
里的东西必须是可以哈希的,也就是说,它们需要有一个叫做 __hash__
的特殊方法(据我所知,这个方法是用来在树中排序的)。而 list
并没有这个特殊方法,所以它不能被放进 set
里。
5
在这一行:
s.add([10])
你是在尝试把一个列表整体添加到集合里,而不是把列表里的每个元素添加进去。如果你想把列表里的元素添加到集合中,可以使用更新(update)方法。
17
当你初始化一个集合时,你需要提供一系列的值,这些值必须是可以被“哈希”的,也就是说它们必须是唯一的。
s = set()
s.add([10])
这和下面的写法是一样的
s = set([[10]])
这会抛出和你现在看到的相同的错误。