Python 中“集合”有两种,set
和它的不可变的姊妹类型frozenset
,它们实现也依赖“散列表”,但在它们的散列表里存放的只有元素的引用(就像在字典里只存放键而没有相应的值)。
集合的本质是许多唯一对象的聚集。因此,集合可以用于去重:
# 集合的本质是许多唯一对象的集合,所以可以用来去重:
s = ['spam', 'spam', 'eggs', 'spam']
ls = set(s) # 返回一个新集合
print(ls) # {'spam', 'eggs'}
集合中的元素必须是可散列的,set
类型本身是不可散列的,但是 frozenset
可以。因此有需求的时候可以创建一个包含不同 frozenset
的 set
。
3.8.1 集合字面量
1. 创建 set 推荐使用字面量的方式,字面量比构造方法性能更快,更易读;:s = {1, 2, 3};
2. 如果创建空 set 只能使用构造方法: s = set();
3. frozenset 只能通过构造方法来创建:fs = frozenset();
3.8.2 集合推导
从示例中还可以看出集合是无序的这个特点:
s = 'Hello Python!'
ls = {i.upper() for i in s}
print(ls) # {'T', 'O', 'Y', '!', 'L', 'P', ' ', 'H', 'N', 'E'}
3.8.3 集合的操作
表3-2:集合的数学运算:这些方法或者会生成新集合,或者会在条件允许的情况下就地修改集合
数学符号 | Python运算符 | 方法 | 描述 |
---|---|---|---|
S ∩ Z | s & z | s.__and__(z) | s 和 z 的交集 |
z & s | s.__rand__(z) | 反向 & 操作 | |
s.intersection(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,然后求它们与 s 的交集 | ||
s &= z | s.__iand__(z) | 把 s 更新为 s 和 z 的交集 | |
s.intersection_update(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,然后求得它们与 s 的交集,然后把 s 更新成这个交集 | ||
S ∪ Z | s | z | s.__or__(z) | s 和 z 的并集 |
z | s | s.__ror__(z) | | 的反向操作 | |
s.union(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,然后求它们和 s 的并集 | ||
s |= z | s.__ior__(z) | 把 s 更新为 s 和 z 的并集 | |
s.update(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,然后求它们和 s 的并集,并把 s 更新成这个并集 | ||
S \ Z | s - z | s.__sub__(z) | s 和 z 的差集,或者叫作相对补集 |
z - s | s.__rsub__(z) | - 的反向操作 | |
s.difference(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,然后求它们和 s 的差集 | ||
s -= z | s.__isub__(z) | 把 s 更新为它与 z 的差集 | |
s.difference_update(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,求它们和 s 的差集,然后把 s 更新成这个差集 | ||
s.symmetric_difference(it) | 求 s 和 set(it) 的对称差集 | ||
S △ Z | s ^ z | s.__xor__(z) | 求 s 和 z 的对称差集 |
z ^ s | s.__rxor__(z) | ^ 的反向操作 | |
s.symmetric_difference_update(it, ...) | 把可迭代的 it 和其他所有参数转化为集合,然后求它们和 s 的对称差集,最后把 s 更新成该结果 | ||
s ^= z | s.__ixor__( | 把 s 更新成它与 z 的对称差集 |
表3-3:集合的比较运算符,返回值是布尔类型
数学符号 | Python 运算符 | 方法 | 描述 |
---|---|---|---|
s.isdisjoint(z) | 查看 s 和 z 是否不相交(没有共同元素) | ||
e ∈ S | e in s | s.__contains__(e) | 元素 e 是否属于 s |
S ⊆ Z | s <= z | s.__le__(z) | s 是否为 z 的子集 |
s.issubset(it) | 把可迭代的 it 转化为集合,然后查看 s 是否为它的子集 | ||
S ⊂ Z | s < z | s.__lt__(z) | s 是否为 z 的真子集 |
S ⊇ Z | s >= z | s.__ge__(z) | s 是否为 z 的父集 |
s.issuperset(it) | 把可迭代的 it 转化为集合,然后查看 s 是否为它的父集 | ||
S ⊃ Z | s > z | s.__gt__(z) | s 是否为 z 的真父集 |
表3-4:集合类型的其他方法
|
|
|
|
---|---|---|---|
| • |
| 把元素 |
| • |
| 移除掉 |
| • | • | 对 |
| • |
| 如果 |
| • | • | 返回 |
| • | • |
|
| • |
| 从 |
| • |
| 从 |