理解Python集合的行为

11 投票
6 回答
8196 浏览
提问于 2025-04-16 11:57

内置类型 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]])

这会抛出和你现在看到的相同的错误。

撰写回答