Python 教程 15:集合
“世界上没有两片完全相同的树叶。”
集合(Set)是 Python 中一个特殊的数据结构,它最大的特点是元素唯一、无序。就像数学中的集合概念,非常适合去重和集合运算。
1. 什么是集合
集合是一个无序的、不重复的元素集合。
1# 创建集合
2empty_set = set() # 空集合(注意不是{})
3numbers = {1, 2, 3, 4, 5}
4mixed = {1, "hello", 3.14, True}
5
6# 使用set()函数
7from_list = set([1, 2, 2, 3, 3, 3]) # {1, 2, 3}(自动去重)
8from_string = set("hello") # {'h', 'e', 'l', 'o'}
9
10# 集合推导式
11squares = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
注意:{}是空字典,不是空集合!
1empty_dict = {}
2empty_set = set()
3
4print(type(empty_dict)) # <class 'dict'>
5print(type(empty_set)) # <class 'set'>
2. 集合的基本操作
1fruits = {"苹果", "香蕉", "橙子"}
2
3# 添加元素
4fruits.add("葡萄")
5print(fruits) # {'苹果', '香蕉', '橙子', '葡萄'}
6
7# 添加多个元素
8fruits.update(["西瓜", "芒果"])
9print(fruits)
10
11# 删除元素
12fruits.remove("香蕉") # 不存在会报错
13# fruits.remove("榴莲") # KeyError
14
15fruits.discard("橙子") # 不存在不报错
16fruits.discard("榴莲") # 不会报错
17
18# pop():randomly删除并返回一个元素
19item = fruits.pop()
20print(f"删除了:{item}")
21
22# clear():清空
23fruits.clear()
3. 集合运算
集合支持数学中的集合运算:
1a = {1, 2, 3, 4, 5}
2b = {4, 5, 6, 7, 8}
3
4# 并集(Union):所有元素
5print(a | b) # {1, 2, 3, 4, 5, 6, 7, 8}
6print(a.union(b))
7
8# 交集(Intersection):共同元素
9print(a & b) # {4, 5}
10print(a.intersection(b))
11
12# 差集(Difference):在a但不在b
13print(a - b) # {1, 2, 3}
14print(a.difference(b))
15
16# 对称差集(Symmetric Difference):不同时在a和b中
17print(a ^ b) # {1, 2, 3, 6, 7, 8}
18print(a.symmetric_difference(b))
集合关系判断
1a = {1, 2, 3}
2b = {1, 2, 3, 4, 5}
3c = {1, 2, 3}
4
5# 子集
6print(a.issubset(b)) # True(a是b的子集)
7print(a <= b) # True
8
9# 超集
10print(b.issuperset(a)) # True(b是a的超集)
11print(b >= a) # True
12
13# 相等
14print(a == c) # True
15
16# 不相交
17x = {1, 2}
18y = {3, 4}
19print(x.isdisjoint(y)) # True(没有共同元素)
4. 集合的应用
应用 1:去重
1# 列表去重
2numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
3unique = list(set(numbers))
4print(unique) # [1, 2, 3, 4](顺序可能不同)
5
6# 保持顺序的去重
7def unique_list(lst):
8 seen = set()
9 result = []
10 for item in lst:
11 if item not in seen:
12 seen.add(item)
13 result.append(item)
14 return result
15
16numbers = [1, 2, 2, 3, 1, 4, 3]
17print(unique_list(numbers)) # [1, 2, 3, 4]
应用 2:成员测试
1# 集合的成员测试比列表快得多
2large_set = set(range(1000000))
3large_list = list(range(1000000))
4
5# 集合查找:O(1)
6print(999999 in large_set) # 很快
7
8# 列表查找:O(n)
9print(999999 in large_list) # 相对较慢
应用 3:找共同好友
1alice_friends = {"Bob", "Charlie", "David", "Eve"}
2bob_friends = {"Alice", "Charlie", "Frank", "Grace"}
3
4# 共同好友
5common = alice_friends & bob_friends
6print(f"共同好友:{common}") # {'Charlie'}
7
8# Alice认识但Bob不认识的人
9alice_only = alice_friends - bob_friends
10print(f"Alice独有的朋友:{alice_only}")
5. 注意事项
集合元素必须不可变
1# 可以的
2valid_set = {1, "hello", (1, 2)}
3
4# 不可以的
5# bad_set = {[1, 2]} # TypeError: 列表不可哈希
6# bad_set = {{1, 2}} # TypeError: 集合不可哈希
集合无序
1s = {3, 1, 4, 1, 5, 9, 2, 6}
2print(s) # 输出顺序不确定
3
4# 不能用索引
5# print(s[0]) # TypeError: 集合不支持索引
6. 冻结集合(Frozenset)
不可变的集合,可以作为字典的键:
1# 创建frozenset
2fs = frozenset([1, 2, 3, 4])
3print(fs) # frozenset({1, 2, 3, 4})
4
5# 不能修改
6# fs.add(5) # AttributeError
7
8# 可以作为字典的键
9d = {frozenset([1, 2]): "value"}
10
11# 可以作为集合的元素
12set_of_sets = {frozenset([1, 2]), frozenset([3, 4])}
7. 集合 vs 列表 vs 字典
| 特性 | 集合 | 列表 | 字典 |
|---|---|---|---|
| 有序 | 否 | 是 | 是(3.7+) |
| 重复 | 否 | 是 | 键不重复 |
| 索引 | 否 | 是 | 键访问 |
| 查找 | O(1) | O(n) | O(1) |
| 用途 | 去重、运算 | 序列 | 映射 |
8. 小结
今天我们学习了集合:
- 特性:无序、不重复、可变
- 创建:
{}、set()、推导式 - 操作:add、remove、discard、pop
- 运算:并集、交集、差集、对称差集
- 判断:子集、超集、相等、不相交
- 应用:去重、快速查找、集合运算
- 限制:元素必须不可变
- frozenset:不可变集合
集合是处理去重和集合运算的最佳选择。
练习题:
- 从两个列表中找出共同元素
- 统计两段文本的不同单词数
- 判断一个列表是否是另一个列表的子集
本文代码示例:
关注公众号:极客老墨
更多 AI 应用开发、工程实践和效率工具分享,欢迎扫码关注。
