1. 集合是什么? #
- 集合(set)是无序、元素互不相同的可变容器,用花括号
{1, 2, 3} 或 set() 创建。
- 与列表不同:没有下标,不能
s[0] 按位置访问;重复添加同一元素只会保留一份。
- 成员检测
x in s 平均很快,适合「判断是否出现过」「两批 ID 有无交集」这类场景。
- 放入集合的元素必须是可哈希、不可变的类型(数字、字符串、元组等)。
- 列表、字典、集合本身可变,不能作为元素,否则会
TypeError。
- 需要「集合的集合」时,可用不可变版
frozenset。
tags = {"python", "web", "api"}
print({1, 2, 2, 3})
2. 创建集合 #
- 字面量
{1, 2, 3} 直接得到集合;空集合必须写 set(),因为 {} 表示空字典。
- 从列表、元组等可迭代对象构造用
set(iterable),会按唯一性去重,但不保证顺序。
- 项目里极常见的写法:
list(set(ids)) 给 ID 列表去重。
- 若业务要求保留首次出现顺序,不能单靠
set,可用 dict.fromkeys(items) 等技巧。
nums = {1, 2, 3}
empty = set()
ids = [1, 2, 2, 3, 3]
unique_ids = list(set(ids))
3. 增删与查询 #
- 集合支持原地
add 单个元素、update 批量并入(类似列表的 extend)。
- 删除时
discard(x) 更安全:元素不存在也不报错。
remove(x) 在不存在时会抛 KeyError,行为类似字典的 remove。
- 查询用
x in s、len(s) 即可,没有「按索引取第几个」的 API。
- 遍历顺序每次运行可能不同,不要依赖集合的迭代顺序做业务逻辑。
| 方法 |
作用 |
add(x) |
添加一个元素 |
update(iterable) |
批量添加 |
discard(x) |
删除元素,不存在也不报错 |
remove(x) |
删除元素,不存在抛 KeyError |
s = {"a", "b"}
s.add("c")
print("a" in s)
s.discard("a")
print("a" in s)
print(len(s))
4. 集合运算 #
- 集合在数学意义上的并、交、差、对称差都有对应运算符,也可用
.union()、.intersection() 等方法。
- 结果多为新集合(运算符写法更常见)。
- 典型业务:两批用户标签求交集、已浏览未购买页面求差集、两环境配置求对称差。
- 并集:
a | b 或 a.union(b),所有元素
- 交集:
a & b 或 a.intersection(b),共有元素
- 差集:
a - b 或 a.difference(b),在 a 不在 b
- 对称差:
a ^ b,只在其中一个里
viewed = {"home", "cart", "pay"}
purchased = {"cart", "pay"}
print("并集:", viewed | purchased)
print("并集 (union):", viewed.union(purchased))
print("交集:", viewed & purchased)
print("交集 (intersection):", viewed.intersection(purchased))
print("差集:", viewed - purchased)
print("差集 (difference):", viewed.difference(purchased))
print("对称差:", viewed ^ purchased)
5. 遍历 #
- 只能用
for item in s 逐个取出元素,不能按索引遍历。
- 集合无序,每次运行、不同机器上
for 的顺序都可能不同。
- 不要写「第一个元素一定是某某」之类的逻辑。
- 需要固定顺序时,先
sorted(s) 得到列表再遍历,或一开始就用列表。
for tag in tags:
print(tag)
6. 列表 vs 集合:何时用 #
- 要顺序、要重复、要按下标改 → 列表;要去重、要快查成员、要做集合运算 → 集合。
- 很多接口返回的是列表,内存里临时转成
set 做去重或 in 判断,再转回 list 返回给前端也很常见。
| 需求 |
用 |
| 有序、可重复、按索引 |
列表 |
去重、快速 in 判断 |
集合 |
| 并/交/差运算 |
集合 |
7. 项目开发要点 #
- 集合在 CRUD 业务里不如列表显眼,但在去重、权限/标签判断、批量 ID 对比时非常省事。
- 去重:
list(set(items));若需保留顺序,用 dict.fromkeys(items) 等(后续可学)。
- 成员判断:大量 ID 是否已存在,用
set 比 list 快。
- 空集合:
set(),不要写 {}。
- 不能放列表当元素:嵌套结构先去重键或转元组/
frozenset。
- 业务里常用:标签集合、权限集合、两批用户 ID 的交集/差集。
- 需要顺序或重复:仍用列表,不要强行用集合。