一、Python集合类型
Python集合类型包括 set 和 frozenset 两种,set 对象是由具有唯一性的可 hashable对象组成的无序多项集。常见用途是成员检测、去重和数学中的集合类计算,如交集、并集、差集和对称差集等操作。与其他多项集一样,集合也支持 x in set, len(set) 和 for x in set 操作,但不支持索引、切片或其他序列类的操作。
set 类型是可变的,它的内容可以使用 add() 和 remove() 等方法来改变。由于是可变类型,它没有哈希值,不能被用作字典的键或其他集合的元素。frozenset 类型是不可变的,其内容在创建后不能改变,因此可以被用作字典的键或其他集合的元素
除了可以使用 set 构造器,非空的 set 还可以通过将以逗号分隔的元素列表包含于花括号之内来创建,例如: {‘jack’, ‘sjoerd’}。两个构造器的作用相同,都可以从可迭代对象中创建集合。
两个类的构造器具有相同的作用方式:
返回一个新的 set 或 frozenset 对象,其元素来自于 iterable。 集合的元素必须为 hashable。 要表示由集合对象构成的集合,所有的内层集合必须为 frozenset 对象。 如果未指定 iterable,则将返回一个新的空集合。
二、Python集合创建
集合可用多种方式来创建:
- 使用花括号内以逗号分隔元素的方式: {‘jack’, ‘sjoerd’}
- 使用集合推导式: {c for c in ‘abracadabra’ if c not in ‘abc’}
- 使用类型构造器: set(), set(‘foobar’), set([‘a’, ‘b’, ‘foo’])
三、Python集合操作
set 和 frozenset 的实例提供以下操作:
- len(s):返回集合 s 中的元素数量(即 s 的基数)。
- x in s:检测 x 是否为 s 中的成员。
- x not in s:检测 x 是否非 s 中的成员。
- isdisjoint(other):如果集合中没有与 other 共有的元素则返回 True。 当且仅当两个集合的交集为空集合时,两者为不相交集合。
- issubset(other) set <= other:检测是否集合中的每个元素都在 other 之中。
- set < other:检测集合是否为 other 的真子集,即 set <= other and set != other。
- issuperset(other) set >= other:检测是否 other 中的每个元素都在集合之中。
- set > other:检测集合是否为 other 的真超集,即 set >= other and set != other。
- union(*others) set | other | …:返回一个新集合,其中包含来自原集合以及 others 指定的所有集合中的元素。
- intersection(*others) set & other & …:返回一个新集合,其中包含原集合以及 others 指定的所有集合中共有的元素。
- difference(*others) set – other – …:返回一个新集合,其中包含原集合中在 others 指定的其他集合中不存在的元素。
- symmetric_difference(other) set ^ other:返回一个新集合,其中的元素或属于原集合或属于 other 指定的其他集合,但不能同时属于两者。
- copy():返回原集合的浅拷贝。
注意: union() 、 intersection() 、 difference() 、 symmetric_difference() 、 issubset() 和 issuperset() 方法的非运算符版本可以接受任何可迭代对象作为一个参数。相比之下,基于运算符的对应方法则要求参数为集合对象。这就避开了像 set(‘abc’) & ‘cbs’ 这样容易出错的结构,而换成了可读性更好的 set(‘abc’).intersection(‘cbs’)。
set 和 frozenset 均支持集合与集合的比较。 两个集合当且仅当每个集合中的每个元素均包含于另一个集合之内(即各为对方的子集)时则相等。 一个集合当且仅当其为另一个集合的真子集(即为后者的子集但两者不相等)时则小于另一个集合。 一个集合当且仅当其为另一个集合的真超集(即为后者的超集但两者不相等)时则大于另一个集合。
set 的实例与 frozenset 的实例之间基于它们的成员进行比较。 例如 set(‘abc’) == frozenset(‘abc’) 返回 True,set(‘abc’) in set([frozenset(‘abc’)]) 也一样。子集与相等比较并不能推广为完全排序函数。 例如,任意两个非空且不相交的集合不相等且互不为对方的子集,因此以下 所有 比较均返回 False: a<b, a==b, or a>b。
由于集合仅定义了部分排序(子集关系),因此由集合构成的列表 list.sort() 方法的输出并无定义。集合的元素,与字典的键类似,必须为 hashable。混合了 set 实例与 frozenset 的二进制位运算将返回与第一个操作数相同的类型。例如: frozenset(‘ab’) | set(‘bc’) 将返回 frozenset 的实例。
下表列出了可用于 set 而不能用于不可变的 frozenset 实例的操作:
- update(*others) set |= other | …:更新集合,添加来自 others 中的所有元素。
- intersection_update(*others) set &= other & …:更新集合,只保留其中在所有 others 中也存在的元素。
- difference_update(*others) set -= other | …:更新集合,移除其中也存在于 others 中的元素。
- symmetric_difference_update(other) set ^= other:更新集合,只保留存在于集合的一方而非共同存在的元素。
- add(elem):将元素 elem 添加到集合中。
- remove(elem):从集合中移除元素 elem。 如果 elem 不存在于集合中则会引发 KeyError。
- discard(elem):如果元素 elem 存在于集合中则将其移除。
- pop():从集合中移除并返回任意一个元素。 如果集合为空则会引发 KeyError。
- clear():从集合中移除所有元素。
注意:
- 非运算符版本的 update(), intersection_update(), difference_update() 和 symmetric_difference_update() 方法将接受任意可迭代对象作为参数。
- __contains__(), remove() 和 discard() 方法的 elem 参数可能是一个 set。 为支持对一个等价的 frozenset 进行搜索,会根据 elem 临时创建一个该类型对象。