Python 从零开始 · 第 5 课:字典与集合——按键查值、自动去重
上一课我们用列表一次存一堆数据。但列表有个痛点:它靠"下标"找数据。你想找"张三的成绩",得先知道张三排在第几个位置,或者一个个扫过去。
现实里我们更习惯这样:直接喊名字,就知道成绩。
scores = {"张三": 90, "李四": 85, "王五": 78}
print(scores["张三"]) # 90,直接按名字拿这就是这一课的主角——字典(dict)。它让你能"按键查值",而且快到离谱。
一、字典:键值对的仓库
字典用花括号 {},里面是一对一对的 键(key): 值(value):
person = {
"name": "张三",
"age": 20,
"city": "北京"
}
print(person["name"]) # 张三
print(person["age"]) # 20- 键:就是"名字",用来查找。必须是不可变的(字符串、数字、元组可以;列表不行)。
- 值:任何东西都可以,数字、字符串、列表、甚至另一个字典。
二、增删改查
d = {}
d["name"] = "张三" # 增:直接赋值就是新增
d["age"] = 20
d["age"] = 21 # 改:键已存在,赋值就是覆盖
print(d["name"]) # 查:按键取值
del d["age"] # 删:删除键值对
"name" in d # 判断键是否存在(O(1) 快)⚠️ 查一个不存在的键会报错KeyError。想安全地查,用d.get("key", 默认值):
print(d.get("age", "没有这个键")) # 键不存在时返回默认值,不报错三、遍历字典
d = {"a": 1, "b": 2, "c": 3}
for k in d: # 遍历键
print(k)
for v in d.values(): # 遍历值
print(v)
for k, v in d.items(): # 同时遍历键和值
print(k, v)四、集合:自动去重 + 闪电判断
集合(set)可以理解成"没有值的字典",或者"不能有重复元素的列表"。用花括号 {}:
s = {1, 2, 3, 3, 3}
print(s) # {1, 2, 3} 重复的自动去掉了
s.add(4) # 加一个
s.remove(2) # 删一个
2 in s # 判断在不在,O(1) 闪电快
len(s) # 元素个数集合最厉害的两件事:
- 去重:把一个列表丢进
set(),重复的瞬间没。 - 成员判断:
x in s是 O(1),比列表的x in list(O(n))快几百上千倍。
🧊 冷笑话:A 说"我脑子里有一堆重复的想法"。B 说"扔进 set() 里"。A 问"然后呢?"B 答"就只剩一个想法了——'我什么都没了'。"五、集合运算:并、交、差
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a | b # 并集 {1, 2, 3, 4, 5, 6}
a & b # 交集 {3, 4}
a - b # 差集 {1, 2}(在 a 里、不在 b 里)
a ^ b # 对称差 {1, 2, 5, 6}(只在一方的)六、推导式:字典和集合也有
列表有推导式,字典和集合同样有:
# 字典推导式
squares = {x: x*x for x in range(1, 6)}
print(squares) # {1:1, 2:4, 3:9, 4:16, 5:25}
# 集合推导式
evens = {x for x in range(1, 11) if x % 2 == 0}
print(evens) # {2, 4, 6, 8, 10}七、一个高频应用:统计词频
字典 + 集合的经典配合——统计一篇文章里每个词出现了几次:
text = "the cat and the dog and the bird"
words = text.split()
count = {}
for w in words:
count[w] = count.get(w, 0) + 1 # 没见过记 1,见过就 +1
print(count)
# {'the': 3, 'cat': 1, 'and': 2, 'dog': 1, 'bird': 1}这行 count.get(w, 0) + 1 是精髓:get 拿不到就返回 0,然后 +1,巧妙地完成了"计数"。
八、动手时间 🎯
实验 1:电话本
phone = {}
while True:
name = input("输入名字(q 退出):")
if name == "q":
break
if name in phone:
print(f"{name} 的电话是 {phone[name]}")
else:
num = input("没有记录,输入电话存起来:")
phone[name] = num实验 2:列表去重,且保持顺序
nums = [3, 1, 2, 1, 3, 4, 2]
seen = set()
result = []
for x in nums:
if x not in seen:
seen.add(x)
result.append(x)
print(result) # [3, 1, 2, 4]实验 3:找两个列表里都出现的元素
a = [1, 2, 3, 4, 5]
b = [4, 5, 6, 7, 8]
print(set(a) & set(b)) # {4, 5}九、小结
- 字典是"按键查值"的仓库,键要不可变、值随便;
get()能安全查值不报错。 - 集合是"自动去重 + O(1) 判断"的利器,
in快到离谱,还有并交差运算。 - 遇到"查找、去重、计数、判重",先想到字典和集合,能把 O(n) 砍成 O(1)。
下一课,我们学 函数——把一段代码打包、起个名字,随用随调。这是"复用代码"的开始,也是你从"会写几行"迈向"会写程序"的关键一步。
先把「电话本」和「词频统计」敲熟,字典和集合的手感就长在你脑子里了。