sets
sets — Unordered collections of unique elements
2.3版本的新功能。
自2.6版弃用:内置set
/ frozenset
类型替换此模块。
该sets
模块提供了用于构建和操作独特元素的无序集合的类。常见用途包括成员资格测试,删除序列中的重复项以及计算交集,联合,差异和对称差异等集合上的标准数学运算。
像其他收藏品,集支持x in set
,len(set)
和for x in set
。作为无序集合,集合不会记录元素位置或插入顺序。因此,集合不支持索引,切片或其他类序列行为。
大多数设置的应用程序使用Set
提供除了的每种设置方法的类__hash__()
。对于需要散列方法的高级应用程序,ImmutableSet
该类添加了一个__hash__()
方法,但省略了更改该集合内容的方法。双方Set
并ImmutableSet
从派生BaseSet
,一个抽象类,以确定是否东西是一组非常有用:isinstance(obj, BaseSet)
。
设置的类是使用字典实现的。因此,设置元素的要求与字典键的要求相同; 即元素定义了两者__eq__()
和__hash__()
。因此,集合不能包含可变元素,如列表或字典。但是,它们可以包含不可变集合,例如元组或实例ImmutableSet
。为了方便实现集合集合,内部集合自动转换为不可变形式,例如,Set([Set(['dog'])])
转换为Set([ImmutableSet(['dog'])])
。
class sets.Set([iterable])
构造一个新的空Set
对象。如果提供了可选的iterable
参数,则使用从迭代获得的元素更新集合。迭代中的
所有元素都应该是不可变的,或者可以使用协议自动转换为不可变的部分中描述的协议将其转换为不可变的。
class sets.ImmutableSet([iterable])
构造一个新的空ImmutableSet
对象。如果提供了可选的iterable
参数,则使用从迭代获得的元素更新集合。迭代中的
所有元素都应该是不可变的,或者可以使用协议自动转换为不可变的部分中描述的协议将其转换为不可变的。
由于ImmutableSet
对象提供了一种__hash__()
方法,因此它们可以用作集合元素或字典键。ImmutableSet
对象没有添加或删除元素的方法,因此在调用构造函数时必须知道所有元素。
1.设置对象
实例Set
和ImmutableSet
两者都提供以下操作:
手术 | 当量 | 结果 |
---|---|---|
只有(一) | | 集合s中的元素数(基数) |
x in s | | 测试x在s中的成员身份 |
x不在s中 | | 测试x对于s中的非成员资格 |
s.issubset(t)的 | s <= t | 测试s中的每个元素是否在t中 |
s.issuperset(t)的 | s> = t | 测试t中的每个元素是否在s中 |
s.union(t)的 | s | Ť | 包含s和t元素的新集合 |
s.intersection(t)的 | s&t | 与s和t共同的元素的新集合 |
s.difference(t)的 | s - t | 在s中有元素的新集合,但不在t中 |
s.symmetric_difference(t)的 | s ^ t | 在s或t中有元素的新集合,但不是两者都有 |
s.copy() | | 与s的浅拷贝的新的集合 |
注意,对非运营商的版本union()
,intersection()
,difference()
,和symmetric_difference()
将接受任何迭代器作为参数。相反,他们的基于操作员的对应方要求他们的参数是集合。这排除了易于出错的结构,例如Set('abc') & 'cbs'
有利于更具可读性的结构Set('abc').intersection('cbs')
。
在版本2.3.1中更改:以前所有参数都需要设置。
另外,无论Set
和ImmutableSet
支持设置来设置比较。当且仅当每个集合中的每个元素都包含在另一个中(每个元素是另一个的子集)时,两个集合是相等的。当且仅当第一组是第二组的合适子集(是子集,但不相等)时,集合小于另一集合。当且仅当第一个集合是第二个集合的适当超集(是超集,但不相等)时,集合比另一集合大。
子集和等式比较不推广到完整的排序功能。例如,任何两个不相交的集合不相等,并且不彼此的子集,所以所有的以下返回False:a<b,a==b,或a>b。因此,集合不执行该__cmp__()方法。
由于集合只定义了部分排序(子集关系),所以该list.sort()
方法的输出对于集合列表是未定义的。
下表列出了可用于ImmutableSet
但未在Set
以下位置找到的操作:
Operation | 结果 |
---|---|
哈希(S) | 为s返回一个散列值 |
下表列出了可用于Set
但未在ImmutableSet
以下位置找到的操作:
手术 | 当量 | 结果 |
---|---|---|
s.update(t)的 | s | = t | 返回从t添加的元素 |
s.intersection_update(t)的 | s&= t | 返回集只保留t中的元素 |
s.difference_update(t)的 | s - = t | 删除在t中找到的元素后返回集合s |
s.symmetric_difference_update(t)的 | s ^ = t | 使用s或t中的元素返回集合s,但不是两者 |
s.add(x)的 | | 添加元素x来设置s |
s.remove(x)的 | | 从集合s中移除x; 如果不存在,会引发KeyError |
s.discard(x)的 | | 如果存在,则从集合s中移除x |
s.pop() | | 从s中移除并返回任意元素; 如果为空则引发KeyError |
s.clear() | | 从集合s中删除所有元素 |
注意,对非运营商的版本update()
,intersection_update()
,difference_update()
,和symmetric_difference_update()
将接受任何迭代器作为参数。
在版本2.3.1中更改:以前所有参数都需要设置。
还要注意,该模块还包含一个union_update()
用于别名的方法update()
。包含该方法以实现向后兼容。程序员应该更喜欢这种update()
方法,因为它是由内置set()
和frozenset()
类型支持的。
2.例子
>>> from sets import Set
>>> engineers = Set(['John', 'Jane', 'Jack', 'Janice'])
>>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice'])
>>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack'])
>>> employees = engineers | programmers | managers # union
>>> engineering_management = engineers & managers # intersection
>>> fulltime_management = managers - engineers - programmers # difference
>>> engineers.add('Marvin') # add element
>>> print engineers
Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
>>> employees.issuperset(engineers) # superset test
False
>>> employees.update(engineers) # update from another set
>>> employees.issuperset(engineers)
True
>>> for group in [engineers, programmers, managers, employees]:
... group.discard('Susan') # unconditionally remove element
... print group
...
Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack'])
Set(['Janice', 'Jack', 'Sam'])
Set(['Jane', 'Zack', 'Jack'])
Set(['Jack', 'Sam', 'Jane', 'Marvin', 'Janice', 'John', 'Zack'])
3.自动转换为不可变的协议
集只能包含不可变元素。为了方便起见,可变Set
对象被自动复制到一个ImmutableSet
被添加为一个集合元素之前。
该机制总是添加可哈希元素,或者如果它不可哈希,则检查该元素以查看它是否具有__as_immutable__()
返回不可变等价物的方法。
由于Set
对象有一个__as_immutable__()
返回实例的方法ImmutableSet
,因此可以构造一组集合。
需要散列元素来检查集合中的成员资格的方法__contains__()
和remove()
方法需要类似的机制。这些方法检查的元件为hashability和,如果没有,检查一个__as_temporarily_immutable__()
返回通过提供用于临时方法的类包裹元件方法__hash__()
,__eq__()
和__ne__()
。
备用机制不需要构建原始可变对象的单独副本。
Set
对象实现了__as_temporarily_immutable__()
返回Set
由新类包装的对象的方法_TemporarilyImmutableSet
。
添加可测性的两种机制通常对用户是不可见的; 但是,多线程环境中可能会出现冲突,其中一个线程正在更新一个线程而另一个线程已暂时将其包含在其中_TemporarilyImmutableSet
。换句话说,可变集合集不是线程安全的。
4.与内置套件类型比较
内置set
和frozenset
类型是基于从sets
模块中学到的经验教训设计的。主要区别是:
Set
并ImmutableSet
已更名为set
和frozenset
。
- 没有相当于
BaseSet
。相反,使用isinstance(x, (set, frozenset))
。
- 对于大多数数据集,内置函数的哈希算法执行效率明显更好(碰撞更少)。
- 内置版本拥有更多节省空间的泡菜。
- 内置版本没有
union_update()
方法。相反,使用相同的update()
方法。
- 内置版本没有
_repr(sorted=True)
方法。相反,使用内置repr()
和sorted()
功能:repr(sorted(s))
。
- 内置版本没有自动转换为不可变的协议。许多人发现这个功能令人困惑,社区中没有人报告说它已经找到了真正的用途。