第 22 课 · 阶段三 · 数据结构

推导式与内置函数

推导式是 Python 最优雅的语法糖:一行代码生成列表/字典/集合。这一课掌握推导式与 enumerate、zip 等高阶内置函数。

第 22 课阶段三 · 数据结构难度:进阶建议时长:35 分钟关键词:推导式 · enumerate · zip

🎯 学完本课你将掌握

  • 写出列表、字典、集合推导式
  • 用条件过滤推导式元素
  • 熟练使用 enumerate 与 zip

一、列表推导式

语法:[表达式 for 变量 in 序列],一行替代 for+append 两行。

列表推导式.py
1# 传统写法
2sq = []
3for i in range(1, 6):
4 sq.append(i ** 2)
5
6# 推导式一行搞定
7sq2 = [i ** 2 for i in range(1, 6)]
8print(sq2) # [1, 4, 9, 16, 25]

二、带条件的推导式

条件推导.py
1# 1-20 里的偶数
2evens = [x for x in range(1, 21) if x % 2 == 0]
3print(evens)
4
5# 把字符串转大写
6words = ["apple", "banana", "cherry"]
7upper = [w.upper() for w in words]
8print(upper)

三、字典与集合推导式

字典集合推导.py
1# 字典推导式:{键: 值 for ...}
2square_dict = {x: x ** 2 for x in range(1, 6)}
3print(square_dict) # {1:1, 2:4, 3:9, 4:16, 5:25}
4
5# 集合推导式:自动去重
6s = {x % 3 for x in range(10)}
7print(s) # {0, 1, 2}

四、enumerate:序号 + 值

enumerate.py
1names = ["小明", "小红", "小刚"]
2for i, name in enumerate(names):
3 print(i, name)
4
5# 从 1 开始编号
6for i, name in enumerate(names, 1):
7 print(f"{i}. {name}")

五、zip:并行打包

zip.py
1names = ["小明", "小红", "小刚"]
2scores = [92, 88, 95]
3for name, score in zip(names, scores):
4 print(f"{name}考了{score}分")
5
6# 转成字典
7d = dict(zip(names, scores))
8print(d) # {'小明': 92, '小红': 88, '小刚': 95}
9
10# 解包转回两个列表
11n2, s2 = zip(*d.items())
12print(n2, s2)
✅ 要点
zip(列表1, 列表2) 按最短对齐;zip 后接 dict() 可快速把两列表合成字典,非常常用。

六、推导式 vs 生成器表达式

把方括号改成圆括号就是生成器表达式,它不会一次性生成全部元素,而是惰性逐个产出,省内存(第 32 课深入)。

生成器表达式.py
1total = sum(x * x for x in range(100))
2print(total) # 328350 内存友好

七、常见错误与解决

常见错误与解决

错误现象原因 / 解决方法
推导式里写复杂逻辑报错推导式适合简单逻辑;超过两行逻辑就用普通 for 循环,可读性优先。
zip 后长度对不上zip 按最短序列对齐,想按最长补全可用 itertools.zip_longest。
误把生成器当列表生成器只能用一次、没有 len();需要多次使用就转成 list()。
✍️ 小练习
用推导式生成 1-100 中所有能被 5 整除的数;用 zip 把两个列表合成字典;用 enumerate 给字符串列表加序号输出。
📌 本节小结
推导式一行生成列表/字典/集合,加 if 可过滤;enumerate 带序号、zip 并行打包。这些写法让代码更短更 Pythonic,后续课程会大量使用。