【问题标题】:In Python, how to write a set containing a set? [duplicate]在 Python 中,如何编写包含集合的集合? [复制]
【发布时间】:2013-05-17 23:11:34
【问题描述】:

我们知道,在 Python 中,可以通过写出它的所有元素来定义一个集合,如下所示:

a_set={1,"xyz"}

Python 书籍都说集合的元素可以是任何数据类型。所以我们应该能够写出一个包含一个集合的集合。我试着把它写成:

a_set={1,{"xyz"}}

但是IDLE报错:

Traceback (most recent call last):
  File "<pyshell#58>", line 1, in <module>
    a_set={1,{"xyz"}}
TypeError: unhashable type: 'set'

我认为这可能是因为 Python 试图将其理解为字典。那么,如何在 Python 中写出一个包含集合的集合呢?

【问题讨论】:

  • 虽然它没有直接回答问题,但 Python 常见问题解答中的 Why must dictionary keys be immutable? 与此处相关。集合的值与字典的键基本相同(它们都存储在哈希表中),因此您不能将集合放入集合中,原因与您不能将 dict 用作​​ dict 键的原因相同。

标签: python


【解决方案1】:

最里面的集合必须是 frozenset 类型,这是集合的不可变版本。

>>> a_set = {1, frozenset(['xyz'])}
>>> a_set
set([1, frozenset(['xyz'])])

来自docs

class freezeset([iterable])

返回一个新的 set 或 freezeset 对象,其元素取自可迭代对象。集合的元素必须是可散列的。要表示集合的集合,内部集合必须是 freezeset 对象。如果未指定iterable,则返回一个新的空集。

【讨论】:

  • +1。但是写{1, frozenset({'xyz'})}可能更清楚。
  • Phfff,6 票赞成这个问题,12 票赞成 RTFM 答案? SO 的标准相当低。
【解决方案2】:

集合只能存储不可变的对象,而集合本身是可变的。所以一个集合不能包含另一个集合。

使用frozenset

要表示集合的集合,内部集合必须是frozenset 对象。

【讨论】:

  • 值得注意的是,限制是集合只能包含“可散列”的对象,这些对象通常是但不一定是“不可变的”。例如,未定义 __hash____eq__ 的自定义类的实例是可散列的,但可以通过分配给属性来改变。这是允许的,因为此类对象的哈希不受其内容的影响,仅受其身份影响,因此如果对象发生突变,它不会改变。您可以创建部分可变和部分不可变的对象,并使用不可变部分来定义哈希。
【解决方案3】:

这个例子说明了frozenset的用法:

a_set = frozenset([1,2,3])
b_set = frozenset([1,3])
a_set_copy = frozenset([2,3,1])

set_of_sets = set([a_set, b_set, a_set_copy])

print set_of_sets
# set([frozenset([1, 3]), frozenset([1, 2, 3])])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    相关资源
    最近更新 更多