集合 (Set)
学习集合去重特性、交集并集运算、成员快速判断
集合 (Set)
集合是无序、不重复的元素集合,和数学中的集合概念完全一致。它是去重和成员检查的利器。
学完本章你将掌握: 创建、集合运算、去重、成员检查、冰冻集合。
一、创建集合
python
# 花括号创建
fruits = {"苹果", "香蕉", "橘子"}
# set() 构造函数(从列表去重的好方法)
nums = set([1, 2, 2, 3, 3, 3, 4])
print(nums) # {1, 2, 3, 4} 自动去重!
# 空集合只能用 set(),{} 是空字典!
s = set()
print(type(s)) # <class 'set'>
print(type({})) # <class 'dict'> ← 注意!
二、集合运算
python
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(f"交集: {a & b}") # {3, 4}
print(f"并集: {a | b}") # {1, 2, 3, 4, 5, 6}
print(f"差集: {a - b}") # {1, 2}(a有b没有)
print(f"差集: {b - a}") # {5, 6}(b有a没有)
print(f"对称差: {a ^ b}") # {1, 2, 5, 6}(只在一边的)
# 也可以用方法实现同样操作
print(a.intersection(b))
print(a.union(b))
三、增删元素
python
s = {1, 2, 3}
s.add(4) # 添加
s.add(2) # 已存在,不会重复
s.remove(3) # 删除(元素不存在报 KeyError)
s.discard(5) # 安全删除(不存在也不报错)
popped = s.pop() # 随机删除一个(集合无序)
四、成员检查
集合的 in 是 O(1),比列表快很多:
python
# 模拟:检查 10000 个 ID 是否在白名单中
whitelist = set(range(0, 10000, 2)) # 5000 个偶数
check_ids = range(10000)
count = 0
for n in check_ids:
if n in whitelist: # O(1) 超快!
count += 1
print(f"命中: {count}") # 5000
💡 集合 vs 列表:做成员检查时,集合是 O(1),列表是 O(n)。数据量大时差距巨大。
五、去重实战
python
# 场景:统计访问过网站的用户(自动去重)
visitors = set()
visitors.add("小明")
visitors.add("小红")
visitors.add("小明") # 重复,自动忽略
visitors.add("小刚")
print(visitors) # {'小明', '小红', '小刚'}
print(len(visitors)) # 3(去重后的数量)
# 列表去重并保留顺序
items = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
unique = list(dict.fromkeys(items)) # Python 3.7+ 字典保序
print(unique) # [3, 1, 4, 5, 9, 2, 6]
六、集合推导式
python
# 和列表推导式语法一样,用 {} 而不是 []
squares = {x**2 for x in range(10)}
print(squares) # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
# 带条件
evens = {x for x in range(20) if x % 2 == 0}
print(evens) # {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
七、frozenset(不可变集合)
python
# 普通集合:可变,不能作字典键
s = {1, 2, 3}
# d = {s: "value"} # ❌ TypeError: unhashable type: 'set'
# frozenset:不可变,可以作字典键
fs = frozenset([1, 2, 3])
d = {fs: "value"}
print(d[fs]) # value
八、集合的子集/超集
python
a = {1, 2}
b = {1, 2, 3, 4}
print(a.issubset(b)) # True(a是b的子集)
print(b.issuperset(a)) # True(b包含a)
print(a <= b) # True(等价于 issubset)
print(b >= a) # True(等价于 issuperset)
小结
- 集合自动去重,元素不可重复
&(交)、|(并)、-(差)、^(对称差)add()remove()discard()增删元素in检查是 O(1),比列表快很多frozenset是不可变版本,可作字典键
小练习
- 用集合给
[1,2,2,3,3,3,4,4,4,4]去重 - 找出两个列表
[1,2,3,4]和[3,4,5,6]的交集和并集 - 判断
{1,2}是不是{1,2,3,4}的子集
💬 下一章预告:接下来学习输入与输出——让程序和用户互动。