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:不可变集合

集合是处理去重和集合运算的最佳选择。


练习题

  1. 从两个列表中找出共同元素
  2. 统计两段文本的不同单词数
  3. 判断一个列表是否是另一个列表的子集

本文代码示例

关注公众号:极客老墨

更多 AI 应用开发、工程实践和效率工具分享,欢迎扫码关注。

极客老墨微信公众号二维码

相关阅读