内置类型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'
两者都是清单。在初始化期间是否发生了一些魔术?
答案 0 :(得分:12)
初始化集合时,您需要提供必须每个可以清除的值列表。
s = set()
s.add([10])
与
相同s = set([[10]])
会抛出你现在看到的同样错误。
答案 1 :(得分:5)
In [13]: (2).__hash__
Out[13]: <method-wrapper '__hash__' of int object at 0x9f61d84>
In [14]: ([2]).__hash__ # nothing.
问题是set
需要其项目可以清除,即实现__hash__
魔术方法(据我所知,这用于树中的排序)。 list
不实现该魔术方法,因此无法将其添加到集合中。
答案 2 :(得分:5)
在这一行:
s.add([10])
您正在尝试向列集添加列表,而不是列表的元素。如果您想要添加列表的元素,请使用更新方法。
答案 3 :(得分:1)
它的行为符合文档:set.add()
添加一个元素(因为你给它一个列表,它抱怨它是不可用的 - 因为列表不好像哈希键)。如果要添加元素列表,请使用set.update()
。例如:
>>> s = set([1,2,3])
>>> s.add(5)
>>> s
set([1, 2, 3, 5])
>>> s.update([8])
>>> s
set([8, 1, 2, 3, 5])
答案 4 :(得分:0)
将构造函数视为:
class Set:
def __init__(self,l):
for elem in l:
self.add(elem)
关注为什么需要列表但另一方面add(element)
没有关注,没有什么太有意思了。
答案 5 :(得分:0)
s.add([10])按照记录的方式工作。引发异常,因为[10]不可以删除。
初始化期间没有任何神奇的事情发生。
set([0,1,2,3,4,5,6,7,8,9])与set(范围(10))和set(xrange(10))和set具有相同的效果(
def foo():
for i in (9,8,7,6,5,4,3,2,1,0):
yield i
换句话说,要设置的arg是 iterable ,并且从iterable获取的每个值都必须是可清除的。