为什么不能将集合作为集合的元素?

时间:2014-11-24 20:34:10

标签: python set

在集合中创建{{2}, 3, 4} set元素时,它会给我一个错误。

错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

有没有其他方法可以做到这一点? 提前谢谢。

3 个答案:

答案 0 :(得分:2)

集合只能包含可哈希的对象。但是套装本身并不耐用。所以一个集合不能包含另一个集合。

(除此之外,您的代码有语法错误,因为{2}.3语法无效。但如果您将其更改为{{2}, 3, 4},它仍然无效,原因我上面提到过。)

答案 1 :(得分:2)

在Python中,一般来说,像set这样的可变类型不是hashable。它们不能用作set元素或dict键并不仅仅是巧合 - 这实际上就是重点:

  

如果对象具有在其生命周期内永远不会更改的哈希值(它需要__hash__()方法),并且可以与其他对象进行比较(它需要__eq__()方法),则该对象是可清除的。比较相等的Hashable对象必须具有相同的哈希值。

     

Hashability使对象可用作字典键和set成员,因为这些数据结构在内部使用哈希值。

     

所有Python的不可变内置对象都是可清除的,而没有可变容器(例如列表或字典)。默认情况下,作为用户定义类实例的对象是可清除的;它们都比较不相等(除了它们自己),它们的哈希值来自它们的id()

frozenset类型的存在几乎就是为了这个目的:

  

目前有两种内置集类型,setfrozensetset类型是可变的 - 可以使用add()remove()等方法更改内容。由于它是可变的,因此它没有哈希值,不能用作字典键或另一组的元素。 frozenset类型是不可变和可散列的 - 其内容在创建后不能更改;因此,它可以用作字典键或另一组的元素。

答案 2 :(得分:1)

即使它们的项目必须都是不可变/可散列类型,集合本身也是可变/不可变类型。您可以使用set.addset.popset.remove等方法在集合中添加或删除项目。因此,您不能将一个集合放在另一个集合中,因为该项目可能随时更改。

相反,您可以使用frozenset,这是一个不可变/可散设的集合:

>>> {frozenset({2}), 3,4}
set([frozenset([2]), 3, 4])
>>>

请注意,这只会起作用,因为frozensets在创建后无法更改(无法添加或删除项目)。