Python 编程 - 集合
Python 3 中的集合(set)是一种无序、不重复的元素容器,底层基于哈希表实现,因此成员检测、添加、删除等操作的平均时间复杂度为 O(1)。它非常适合用于去重、关系运算(并、交、差等)和快速成员资格测试。
1. 创建集合
# 使用花括号(注意:空集合不能写成 {},因为那是空字典)
s1 = {1, 2, 3}
# 使用 set() 构造函数,可传入任意可迭代对象
s2 = set([1, 2, 2, 3]) # {1, 2, 3}
s3 = set("hello") # {'h', 'e', 'l', 'o'}(无序)
s4 = set(range(5)) # {0, 1, 2, 3, 4}
# 空集合
empty_set = set()
2. 基本操作(增删改查)
| 方法 / 操作 | 说明 |
|---|---|
s.add(x) |
添加元素 x,若已存在则无影响 |
s.remove(x) |
移除 x,若不存在则抛出 KeyError |
s.discard(x) |
移除 x,若不存在也不报错 |
s.pop() |
随机移除并返回一个元素(集合为空时抛出 KeyError) |
s.clear() |
清空所有元素 |
x in s |
成员测试,返回 True / False |
len(s) |
元素个数 |
s = {1, 2, 3}
s.add(4) # {1,2,3,4}
s.discard(2) # {1,3,4}
s.remove(5) # KeyError!
3. 集合运算(数学操作)
| 运算 | 符号 | 方法 | 说明 |
|---|---|---|---|
| 并集 | | |
union() |
返回两个集合的并集 |
| 交集 | & |
intersection() |
返回交集 |
| 差集 | - |
difference() |
返回在左不在右的元素 |
| 对称差 | ^ |
symmetric_difference() |
返回不同时存在于两集合的元素 |
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # {1,2,3,4,5}
print(a & b) # {3}
print(a - b) # {1,2}
print(a ^ b) # {1,2,4,5}
就地更新版本:update()(|=)、intersection_update()(&=)、difference_update()(-=)、symmetric_difference_update()(^=),它们会修改原集合。
4. 其他常用方法
s.isdisjoint(t):判断 s 与 t 是否不相交(无共同元素)s.issubset(t)(<=):s 是否为 t 的子集s.issuperset(t)(>=):s 是否为 t 的超集s.copy():返回集合的浅拷贝
{1, 2}.issubset({1, 2, 3}) # True
{1, 2}.isdisjoint({3, 4}) # True
5. 集合推导式(Set Comprehension)
与列表推导类似,但使用花括号:
s = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
s = {c.upper() for c in "hello"} # {'H','E','L','O'}
6. 冻结集合(frozenset)
frozenset 是不可变版本,创建后不能修改。它可哈希,因此可以作为字典的键或其他集合的元素。
fs = frozenset([1, 2, 3])
# fs.add(4) # 报错 AttributeError
d = {fs: "value"} # 合法
7. 重要注意事项
- 元素必须可哈希(hashable):即不可变类型(数字、字符串、元组等),列表、字典、集合本身不能作为集合元素。
- 无序性:集合不保证元素顺序,因此不能通过索引访问。
- 性能:成员测试
in比列表快得多(O(1) vs O(n)),适合大型数据去重和查找。
8. 典型应用场景
- 去除列表中的重复项:
list(set(lst)) - 快速检查某元素是否存在
- 计算两组数据的交集、差集等
- 关系数据库中的“投影”或“连接”操作模拟
9. 示例:实用去重与比较
# 去重并保留原顺序(Python 3.7+ 字典有序)
lst = [3, 1, 2, 1, 3]
unique_ordered = list(dict.fromkeys(lst)) # [3,1,2]
# 或使用集合 + 排序(若顺序不重要)
unique = list(set(lst))

浙公网安备 33010602011771号