一、什么是集合运算?
集合运算是指对集合进行数学上的操作,如并集、交集、差集、对称差集等。Python 的 set 类型内置了这些运算,可以通过运算符或方法来完成。这些运算在处理数据去重、比较、筛选时非常有用。
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # 并集:{1, 2, 3, 4, 5}
二、基本集合运算
2.1 并集 —— 合并两个集合的所有元素(去重)
a = {1, 2, 3}
b = {3, 4, 5}
# 使用运算符
print(a | b) # {1, 2, 3, 4, 5}
# 使用方法
print(a.union(b)) # {1, 2, 3, 4, 5}
可以传入多个可迭代对象(不限于集合),union() 会自动将其转换为集合。
print(a.union(b, [6, 7], (8, 9))) # {1, 2, 3, 4, 5, 6, 7, 8, 9}
2.2 交集 —— 两个集合共有的元素
print(a & b) # {3}
print(a.intersection(b)) # {3}
同样支持多个参数:
c = {3, 6}
print(a.intersection(b, c)) # {3}
2.3 差集 —— 在第一个集合但不在第二个集合中的元素
print(a - b) # {1, 2}
print(a.difference(b)) # {1, 2}
注意顺序:a - b 与 b - a 不同。
print(b - a) # {4, 5}
2.4 对称差集 —— 两个集合中不重叠的元素(并集减去交集)
- • 方法:
symmetric_difference()
print(a ^ b) # {1, 2, 4, 5}
print(a.symmetric_difference(b)) # {1, 2, 4, 5}
对称差集相当于 (a | b) - (a & b)。
三、集合关系判断
3.1 子集判断
判断一个集合是否是另一个集合的子集(即所有元素都包含在另一个集合中)。
x = {1, 2}
y = {1, 2, 3}
print(x.issubset(y)) # True
print(x <= y) # True
print(x < y) # True(严格子集,x 不等于 y)
z = {1, 2}
print(z <= y) # True(z 是 y 的子集)
print(z < y) # True(严格)
print(z <= z) # True
print(z < z) # False(不是严格子集)
3.2 超集判断
判断一个集合是否是另一个集合的超集(即包含另一个集合的所有元素)。
print(y.issuperset(x)) # True
print(y >= x) # True
print(y > x) # True
3.3 判断是否不相交
两个集合没有共同元素时,称为不相交。
a = {1, 2}
b = {3, 4}
c = {2, 5}
print(a.isdisjoint(b)) # True
print(a.isdisjoint(c)) # False
四、就地修改集合的运算
以上运算都返回一个新集合。如果希望直接修改原集合,可以使用对应的赋值运算符或方法。
| | |
| | |
| &= | intersection_update() |
| -= | difference_update() |
| ^= | symmetric_difference_update() |
a = {1, 2, 3}
b = {3, 4, 5}
a |= b # 等价于 a.update(b)
print(a) # {1, 2, 3, 4, 5}
a = {1, 2, 3}
a &= b # 等价于 a.intersection_update(b)
print(a) # {3}
a = {1, 2, 3}
a -= b # 等价于 a.difference_update(b)
print(a) # {1, 2}
a = {1, 2, 3}
a ^= b # 等价于 a.symmetric_difference_update(b)
print(a) # {1, 2, 4, 5}
五、集合运算的示例
5.1 并集:合并多个列表并去重
list1 = [1, 2, 3]
list2 = [2, 4, 6]
list3 = [3, 6, 9]
merged = set(list1) | set(list2) | set(list3)
print(merged) # {1, 2, 3, 4, 6, 9}
5.2 交集:找出共同元素
group1 = {"小明", "小红", "小刚"}
group2 = {"小红", "小丽", "小强"}
common = group1 & group2
print(common) # {"小红"}
5.3 差集:找出只在某个组中的人
only_in_group1 = group1 - group2
print(only_in_group1) # {"小明", "小刚"}
5.4 对称差集:找出两个组中不同的人
different = group1 ^ group2
print(different) # {"小明", "小刚", "小丽", "小强"}
5.5 子集判断:权限验证
required_perms = {"read", "write"}
user_perms = {"read", "write", "delete"}
if required_perms <= user_perms:
print("用户拥有所需权限")
5.6 不相交判断:检查数据冲突
ids_used = {101, 102, 103}
new_ids = {104, 105}
if ids_used.isdisjoint(new_ids):
print("无冲突,可以添加")
六、集合运算的效率
集合基于哈希表实现,其运算(并集、交集等)的时间复杂度平均为 O(len(s))。对于大量数据,集合运算非常高效,常用于数据清洗、去重和快速比较。
七、frozenset 的运算
frozenset 是不可变集合,也支持以上所有运算(返回新的 frozenset 或 set,取决于具体方法)。
fs1 = frozenset([1, 2, 3])
fs2 = frozenset([3, 4, 5])
print(fs1 | fs2) # frozenset({1, 2, 3, 4, 5})
由于不可变,它没有就地修改的运算符。
八、注意事项
- 1. 运算符优先级:集合运算符优先级高于比较运算符,低于算术运算符。如有疑问,使用括号明确。
- 2. 参数类型:大部分方法(如
union、intersection)接受任何可迭代对象,而运算符(|、& 等)要求两边都是集合,否则会引发 TypeError。 - 3. 返回值:运算符返回新集合,不会修改原集合;相应的赋值运算符(
|= 等)会修改原集合。 - 4. 空集合:空集合在运算中表现正常,与其他集合运算遵循数学规则。
- 5. 对称差集:
^ 运算符优先级低于 | 和 &,但高于比较运算符,必要时加括号。
九、总结
Python 的集合运算非常强大且易用,可以极大地简化涉及唯一元素和集合关系的代码。
- • 对称差集:
^、symmetric_difference() - • 就地修改:
|=、&=、-=、^= 以及对应的 _update() 方法。
掌握这些运算,能让你的 Python 代码在处理集合数据时更加优雅高效。