为什么不能将集合作为集合的元素? [重复]

问题描述 投票:2回答:3

这个问题在这里已有答案:

它在集合中创建{{2}, 3, 4}集合元素时给出了错误。

错误:

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

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

python set
3个回答
2
投票

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

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

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

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

frozenset类型几乎存在于此目的:

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


2
投票

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

(除此之外,你的代码有一个语法错误,因为{2}.3是无效的语法。但如果你把它改为{{2}, 3, 4}它仍然无法工作,因为我上面提到的原因。)


1
投票

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

相反,你可以使用frozenset,它是一个不可变/可散设集:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.