一、前言
在 Python 中,set(集合) 和 dict(字典) 是两种非常常用但不同的内置数据结构;
虽然它们底层都使用了哈希表,但它们的用途和行为完全不同
二、set示例(去重、集合运算)
my_set = set([1, 2, 3, 2, 1])
print(my_set) # {1, 2, 3}
my_set.add(4)
my_set.remove(2)
print(3 in my_set) # True
# 集合运算
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # 并集:{1, 2, 3, 4, 5}
print(a & b) # 交集:{3}
三、dict 示例(键值对访问)
my_dict = {"name": "Alice", "age": 30}
# 访问
print(my_dict["name"]) # Alice
# 添加或修改
my_dict["age"] = 31
my_dict["city"] = "Beijing"
# 删除
del my_dict["name"]
# 遍历
for k, v in my_dict.items():
print(k, v)
四、总结
特性 |
set (集合) |
dict (字典) |
用途 |
保存唯一的元素集合 |
保存键值对(key-value) |
数据结构 |
无序的、不重复的元素集合 |
无序的、可通过 key 访问的键值对集合 |
访问方式 |
element in my_set |
value = my_dict[key] |
添加元素 |
my_set.add(x) |
my_dict[key] = value |
删除元素 |
my_set.remove(x) |
del my_dict[key] |
支持的操作 |
并集、交集、差集等集合操作 |
仅支持键值管理,不支持集合运算 |
是否支持索引 |
❌ 不支持 |
❌ 不支持 |
可否遍历 |
✅ 可以用 for x in my_set |
✅ 可以用 for k, v in my_dict.items() |
键是否唯一 |
✅ 所有值唯一 |
✅ 所有键唯一 |
值是否唯一 |
✅(集合中就是值) |
❌ 值可以重复 |
五、使用建议
使用场景 |
用 set |
用 dict |
去重、集合运算 |
✅ |
❌ |
保存键值映射(如用户数据) |
❌ |
✅ |
快速检查某元素是否存在 |
✅(用哈希判断) |
✅(键查找) |
数据结构存储复杂对象 |
❌(只能是值) |
✅(可以嵌套任何数据) |
六、注意事项和拓展
1.注意事项!
set 和 dict 中的元素 必须是可哈希的(hashable),比如数字、字符串、元组;
但不能是 list 或 dict!
set 本质上就像一个只有键没有值的字典。
2.什么是可哈希(Hashable)?
在 Python 中,一个对象是否可哈希(hashable),意味着它:
可以用 hash() 函数返回一个固定的整数值(称为哈希值);
它的值是不可变的(immutable);
可以作为字典的 key 或集合(set)中的元素。
判断标准(内建规则)
如果一个对象实现了 hash() 方法,并且 eq() 方法是可靠的,那么它就是可哈希的。
可哈希的对象必须在生命周期中保持哈希值不变(值不可变)。
常见的可哈希 vs 不可哈希对象
一句话总结:可哈希 = 不可变 + 可用于哈希表(如 dict 和 set)中的 key 或元素。
3.为什么list和dict不可哈希?
list 是可变的:
a = [1, 2, 3]
a.append(4) # 可以修改
dict 是键值对结构,内容可变:
d = {'a': 1}
d['b'] = 2 # 字典内容变了
示例:放 list 进 set 会报错:
s = set()
s.add([1, 2, 3])
# ❌ TypeError: unhashable type: 'list'
# 修改为tuple即可
s = set()
s.add((1, 2, 3)) # ✅ OK,因为 tuple 是不可变的
建议
场景:放进 set 或当 dict 的 key —-> 推荐类型:int, str, tuple, frozenset
场景:放进 set 或当 dict 的 key —-> 推荐类型:int, str, tuple, frozenset
4.int和str类型不是也可以改变吗?比如说 [int] num = 1初始化为1,后面重新给num赋值为2,此时不就改变了吗?为什么说该数值类型是不可变的?
关键区别:“变量能改” ≠ “对象能变”
🧠 首先要搞懂的两个概念:
| 变量(name) | :一个名字,指向某个对象(value)的引用
| 对象(value) | :实际的数据,比如 1
、"hello"
、[1, 2, 3]
等
不可变类型(immutable)是什么意思?
当我们说 int 是不可变的类型,意思是:
它一旦创建,它的值就不能被修改,任何“修改”操作其实是创建了一个新对象。
举个例子:
x = 1
print(id(x)) # 比如输出 140736863964176
x = 2
print(id(x)) # 输出变了,比如 140736863964208
虽然你只是对 x 做了重新赋值,但其实:
x = 1:变量 x 指向了对象 1;
x = 2:变量 x 改为指向另一个新对象 2,原来的对象 1 并没有改变。
而如果是可变类型(如 list):
lst = [1, 2, 3]
print(id(lst)) # 假设是 2001
lst.append(4)
print(lst) # [1, 2, 3, 4]
print(id(lst)) # 仍然是 2001 ✅ 同一个对象内容变了
这才是“对象发生了改变”,所以 list 是可变的(mutable)。
小结
作者:在努力的韩小豪