Containers---Set
{}是 dict,不是 set空 set 用set()set 无序 → 不能索引、不能切片set 元素必须可哈希(list/dict/set 不行)remove不存在会报错;discard不报错pop删除哪个不确定Set 是无序、可变、元素唯一的集合,适合去重、快速成员判断和集合运算。如果你想把这一章做得更“考试/工程即用”,我可以再给你加两样:✅10 道 set 预测输出练习题(含答案)✅set
📦 Python Containers 学习笔记 —— Set(集合)【详细版】
1. Set 是什么?
Set 是一种无序(unordered)、可变(mutable)、元素唯一(unique)的容器。
核心特性
-
无序:不保证元素顺序,因此 不能索引、不能切片
-
唯一:不允许重复元素(自动去重)
-
可变:可以增删元素
-
元素要求:set 里放的元素必须是 可哈希(hashable) 的(通常意味着“不可变”)
2. 创建 Set
2.1 直接创建(非空)
s = {1, 2, 3}
2.2 从其他可迭代对象创建(自动去重)
s = set([1, 2, 2, 3]) # {1, 2, 3} s = set((1, 2, 2, 3)) # {1, 2, 3} s = set("banana") # {'b', 'a', 'n'} (字符串按字符拆)
2.3 空集合(⚠️必考坑)
s = set() # ✅ 空 set d = {} # ⚠️ 这是空 dict,不是 set
3. Set 的“无序”意味着什么?
3.1 不能索引
s = {10, 20, 30} s[0] # ❌ TypeError
3.2 不能切片
s[1:3] # ❌ TypeError
3.3 打印顺序不固定(不要依赖输出顺序)
print({3, 1, 2}) # 可能显示 {1, 2, 3},也可能别的顺序(不要当作排序)
4. Set 的元素必须可哈希(hashable)
4.1 可放的典型元素
-
int / float / bool
-
str
-
tuple(前提:tuple 内部也都是可哈希的)
-
frozenset(不可变集合)
s = {1, "a", (1, 2)}
4.2 不能放的典型元素(⚠️重点)
-
list
-
dict
-
set
s = {[1, 2]} # ❌ TypeError: unhashable type: 'list'
4.3 tuple 也可能不行(如果内部含可变对象)
t = (1, [2, 3]) set([t]) # ❌ 因为 [2,3] 不可哈希
5. 成员判断(非常常用 & 很快)
s = {1, 2, 3} 2 in s # True 5 in s # False
📌 典型用法:快速判断“是否访问过 / 是否出现过 / 是否重复”。
6. 添加元素:add 与 update
6.1 add(x):添加一个元素
s = {1, 2} s.add(3) # {1, 2, 3}
-
添加已存在元素不会报错,也不会重复
s.add(2) # 仍然 {1,2,3}
6.2 update(iterable):批量添加(遍历加入)
s = {1, 2} s.update([2, 3, 4]) # {1, 2, 3, 4}
-
类似 list 的
extend:把参数“摊开”逐个加入 -
⚠️ 传字符串会按字符加入
s = set() s.update("hi") # {'h', 'i'}
7. 删除元素:remove / discard / pop / clear
7.1 remove(x):删除指定元素(不存在会报错)
s = {1, 2, 3} s.remove(2) # {1, 3} s.remove(99) # ❌ KeyError
7.2 discard(x):安全删除(不存在不报错)
s = {1, 2, 3} s.discard(2) # {1, 3} s.discard(99) # ✅ 不报错
✅ 建议:不确定元素是否存在时优先用 discard
7.3 pop():删除并返回一个元素(⚠️顺序不确定)
s = {1, 2, 3} x = s.pop() # x 是某个元素(不保证是 1/2/3 中哪个)
-
⚠️ 不要用 pop 期待“拿到最后一个”,set 没有“最后”
-
空 set pop 会报错
set().pop() # ❌ KeyError
7.4 clear():清空集合
s.clear() # set()
8. 集合运算(Set 的灵魂)
设:
A = {1, 2, 3} B = {3, 4}
8.1 并集 union(A 或 B)
方法:
A.union(B) # {1, 2, 3, 4}
运算符:
A | B # {1, 2, 3, 4}
8.2 交集 intersection(A 且 B)
A.intersection(B) # {3} A & B # {3}
8.3 差集 difference(在 A 不在 B)
A.difference(B) # {1, 2} A - B # {1, 2}
8.4 对称差 symmetric_difference(只在其中一个集合)
A.symmetric_difference(B) # {1, 2, 4} A ^ B # {1, 2, 4}
9. 原地更新(in-place)集合运算(会修改原集合)
9.1 运算符形式
A |= B # A = A ∪ B A &= B # A = A ∩ B A -= B # A = A - B A ^= B # A = 对称差更新
9.2 方法形式(等价)
A.update(B) A.intersection_update(B) A.difference_update(B) A.symmetric_difference_update(B)
📌 区分重点:
-
A.union(B)不改 A(返回新集合) -
A.update(B)会改 A
10. 常用辅助:长度与复制
10.1 长度
len(s)
10.2 复制
t = s.copy()
11. 常见坑总结(必背)
-
{}是 dict,不是 set -
空 set 用
set() -
set 无序 → 不能索引、不能切片
-
set 元素必须可哈希(list/dict/set 不行)
-
remove不存在会报错;discard不报错 -
pop删除哪个不确定
12. 典型应用场景(工程直觉)
-
去重:
unique = set(data) -
快速查找/过滤:
if x in visited: ... -
集合运算:共同元素 / 差异元素 / 合并标签
-
状态管理:已访问节点、权限集合、有效 ID 集合
13. 一句话总结(背诵版)
Set 是无序、可变、元素唯一的集合,适合去重、快速成员判断和集合运算。
如果你想把这一章做得更“考试/工程即用”,我可以再给你加两样:
-
✅ 10 道 set 预测输出练习题(含答案)
-
✅ set vs list vs tuple vs dict 一页终极对照表
Appendix
一句话定义(先记住这个)
可哈希(hashable) = 这个对象能被“稳定地”当作唯一标识来用
只要一个东西 能当 set 的元素,或 dict 的 key,它就是可哈希的。
二、直觉理解(人话版)
你可以把 hash 理解成:
给每个对象算一个“身份证号”
-
可哈希对象:身份证号一旦算出来,永远不变
-
不可哈希对象:身份证号可能会变 → 那就不安全
📌 Python 要求:
-
set/dict里的元素 必须能稳定定位 -
否则一改内容,“你是谁”就变了,Python 会乱
三、技术定义(标准版)
一个对象是 hashable,必须满足:
1️⃣ 实现了 __hash__()
2️⃣ 实现了 __eq__()
3️⃣ 对象的值在生命周期内不可变
并且有一个约定:
如果
a == b,那么hash(a) == hash(b)
四、哪些东西是“可哈希”的?(必记)
✅ 可哈希(常见)
-
int -
float -
bool -
str -
tuple(前提:内部元素也都可哈希) -
frozenset
hash(10) hash("abc") hash((1, 2, 3))
❌ 不可哈希(重点)
-
list -
dict -
set
hash([1, 2]) # ❌ TypeError hash({1: 2}) # ❌ TypeError
五、为什么 list / dict / set 不可哈希?(核心原因)
因为它们 是可变的。
a = [1, 2, 3]
如果 list 能当 key:
-
改内容前:hash = X
-
改内容后:hash = Y
那 Python 在 set / dict 里就 找不到它原来的位置了。
👉 这是灾难
六、一个经典对比例子(考试爱考)
tuple 为什么能当 key?
d = {(1, 2): "ok"}
但这个不行:
d = {([1, 2]): "no"} # ❌
📌 原因:
-
(1, 2)不可变 → hash 稳定 -
[1, 2]可变 → hash 不稳定
⚠️ tuple 也可能不可哈希
t = (1, [2, 3]) hash(t) # ❌
因为:
-
tuple 里 包含了不可哈希的 list
📌 规则是:
tuple 可哈希 ⇔ 内部所有元素都可哈希
七、你在 set 里遇到的所有“神秘报错”,本质都是这个
TypeError: unhashable type: 'list'
翻译成人话:
你试图把一个“会变的东西”当作唯一标识
八、给你一版「可直接放进笔记的总结」
你可以直接复制👇
可哈希(hashable)
可哈希对象是指:其值在生命周期内不可改变,并能计算出稳定的 hash 值。
-
可哈希对象可以作为
set的元素或dict的 key -
不可哈希对象不能用于上述用途
常见可哈希类型:
-
int,float,bool -
str -
tuple(内部元素也必须可哈希) -
frozenset
不可哈希类型:
-
list -
dict -
set
原因:
-
可变对象的 hash 值可能改变,无法作为稳定标识。
更多推荐



所有评论(0)