PYTHON LESSON 039
一行代码的魔法
掌握列表解析的写法,会用 zip 和 enumerate 优雅地遍历数据。
00 · 学习目标
这一课要解决什么?
学完后,你应该能够
- [表达式 for x in range(...)] 列表解析
- [x for x in ... if 条件] 带筛选的解析
- zip 配对遍历、enumerate 带序号遍历
01 · 核心概念
列表解析、zip 与 enumerate
列表解析、zip 与 enumerate:以前生成平方列表要写三行:建空列表、循环、append。列表解析把这三件事压缩进一对方括号:[n * n for n in range(1, 11)]——“对每个 n,算出 n*n,装成列表”。
GESP Python 3 级 · 列表解析GESP Python 3 级 · 常用内置函数流程图是算法的表示方法,不是 Python 语法。
02 · 语法与规则
先记住这 3 条,再开始写程序
[表达式 for x in range(...)] 列表解析先准确读出这条写法的结构与作用。
[x for x in ... if 条件] 带筛选的解析换一组最小数据,手工推演一次结果。
zip 配对遍历、enumerate 带序号遍历再用边界值或反例确认它的适用条件。
03 · 完整实例
代码、运行结果和解释放在一起看
# 一行代码的魔法:列表解析、zip 与 enumerate
squares = [n * n for n in range(1, 11)]
print("1 到 10 的平方:", squares)
evens = [n for n in range(1, 21) if n % 2 == 0]
print("20 以内的偶数:", evens)
names = ["小明", "小红", "小刚"]
scores = [88, 95, 79]
for name, score in zip(names, scores):
print(name, "考了", score, "分")
for i, name in enumerate(names):
print("学号", i + 1, "号:", name)1 到 10 的平方: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 20 以内的偶数: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 小明 考了 88 分 小红 考了 95 分 小刚 考了 79 分 学号 1 号: 小明 学号 2 号: 小红 学号 3 号: 小刚
列表解析 = 把“循环 + append”压缩成一行,读熟了反而更清晰。
04 · 逐步理解
每一步只解决一个问题
- 01
从三行到一行
以前生成平方列表要写三行:建空列表、循环、append。列表解析把这三件事压缩进一对方括号:[n * n for n in range(1, 11)]——“对每个 n,算出 n*n,装成列表”。
squares = [n * n for n in range(1, 11)] - 02
加上筛选条件
方括号尾巴上接一个 if,就只有满足条件的元素能入选:[n for n in range(1, 21) if n % 2 == 0] 挑出所有偶数。循环、加工、筛选,全在一行里。
evens = [n for n in range(1, 21) if n % 2 == 0] - 03
zip:两条列表手拉手
zip(names, scores) 把两个列表按位置配对:(小明,88)、(小红,95)……循环时一次解包出两个值,再也不用手动数下标。配对长度不同时,以短的为准。
for name, score in zip(names, scores): print(name, score) - 04
enumerate:自带号码牌
enumerate(names) 遍历时同时给出序号和值:i 从 0 开始,name 逐个取出。想要学号从 1 开始?用 i + 1,或者 enumerate(names, 1)。
for i, name in enumerate(names): print(i + 1, name) - 05
组合拳:zip + 列表解析
两行成绩求每个人的总分:[a + b for a, b in zip(chinese, math)]——zip 负责配对,解析负责计算,一行搞定。这就是三级考试想看到的“优雅代码”。
totals = [a + b for a, b in zip([80, 90], [75, 95])] print(totals) - 06
什么时候不用解析
列表解析适合“生成新列表”;如果循环里要做打印、判断分支等复杂操作,老老实实写普通 for 更清楚。魔法要用在合适的地方,可读性永远排第一。
05 · 练习与检验
自己写出来,才算真正学会
- 1运行程序,感受一行代码的威力
- 2用列表解析生成 1 到 20 的立方数
- 3给解析加上“只要偶数”的条件
- 4用 zip 配对你和同桌的语文数学成绩
06 · 完整知识
继续理解定义、规则和适用边界
第一次学习先完成上面的六个步骤;需要查定义、核对规则、分析误区或理解“为什么”时,再展开对应知识章。
Python 基础条件、循环与程序流程准确理解 if、for、while、range、break、continue 和循环嵌套,而不是背代码模板。+
正式定义
控制流决定下一条要执行的语句。分支依据布尔条件选择路径;循环在满足规则时重复执行代码块。Python 用冒号和缩进界定代码块。
必须掌握
- if/elif/else 从上到下判断,只执行第一个为真的分支;else 不写条件。
- for 依次取得可迭代对象中的元素;range(start, stop, step) 包含 start、不包含 stop,step 不能为 0。
- while 在每轮开始前检查条件;循环体必须让状态向终止条件推进。
- break 结束最内层循环,continue 跳过本轮剩余语句,循环的 else 仅在没有被 break 终止时执行。
- 嵌套循环的总执行次数通常需要把各层次数相乘;内层 break 不会结束外层循环。
- 边界测试至少覆盖空范围、单个元素、第一项命中、最后一项命中和始终不命中。
常见误区
- range 的右端点多算或少算一次
- while 忘记更新状态造成死循环
- 把两个互斥条件写成两个独立 if
- 误以为 break 会跳出所有嵌套循环
适用边界
- 流程图是算法的表示方法,不是 Python 语法。
- 递归也能表达重复,但有调用开销和递归深度限制,不能无条件代替循环。
核心数据结构列表、元组、字典与集合按顺序、可变性、唯一性和查找需求选择容器,并掌握遍历、推导式、排序与复制。+
正式定义
容器保存多个对象。list 是可变有序序列,tuple 是不可变有序序列,dict 保存唯一键到值的映射,set 保存无序且不重复的可哈希对象。
必须掌握
- list 支持下标、切片、append、extend、insert、pop、remove 与 sort;多数修改方法返回 None。
- tuple 的逗号比括号更关键,单元素元组必须写成 (value,)。
- dict 保持插入顺序;键必须可哈希且唯一,get 可提供缺省值,items 同时遍历键和值。
- set 用于去重与集合运算:| 并、& 交、- 差、^ 对称差;空集合必须写 set()。
- enumerate 同时给出序号和值,zip 并行遍历多个可迭代对象,默认在最短输入处停止。
- 浅复制只复制最外层容器;嵌套可变对象仍可能共享。
常见误区
- 把 list.sort() 的返回值赋回列表
- 遍历 dict 时同时改变其大小
- 用可变 list 当字典键
- 把 set 当成有固定顺序的序列
适用边界
- 大量从队首删除时 list.pop(0) 是 O(n),应使用 collections.deque。
- 需要有序映射的特殊操作、计数或默认值时可查阅 collections,但先理解基本 dict。
Python 基础运算符、表达式与优先级完整区分算术、比较、逻辑、成员、身份和位运算,并用优先级表消除歧义。+
正式定义
表达式求值得到一个值。运算符规定如何组合操作数;当一个表达式含多个运算符时,优先级和结合方向决定求值顺序,括号可以明确改变顺序。
必须掌握
- / 总是得到浮点结果;// 是向负无穷方向取整的整除;% 与 // 满足 a == (a // b) * b + a % b。
- 比较可以链式书写,如 0 <= x < 10;and/or 会短路并返回最后求值的操作数,不一定返回 bool。
- == 比较值是否相等,is 比较是否为同一个对象;判断 None 应写 is None。
- in/not in 做成员测试;对 dict 测试的是键。
- 位运算作用于整数的二进制位;负整数按无限长二进制补码语义理解。
- 复杂表达式即使能靠优先级正确运行,也应使用括号表达意图。
常见误区
- 把 // 当成简单截断
- 用 is 比较数字或字符串的值
- 忘记 and 的优先级高于 or
- 连续位移、比较和逻辑运算却不加括号
适用边界
- 浮点数比较受二进制表示误差影响,需要按问题选择容差。
- 运算符可由自定义类重载,因此相同符号对不同类型可能有不同语义。
程序组织模块、导入与常用标准库正确导入模块,并按用途查找 math、random、statistics、collections、heapq、bisect 等标准工具。+
正式定义
模块是可导入的 Python 代码单元,包把模块组织成层次。import 先加载模块并创建模块对象,再把名字绑定到当前命名空间;标准库随 Python 分发,不等于第三方包。
必须掌握
- import module 保留清晰命名空间;from module import name 只导入指定名字;避免 from module import *。
- math 提供 sqrt、floor、ceil、gcd、log、sin 等数学函数和 pi、e 等常量。
- random 用于伪随机模拟,不适合密码安全;需要安全随机时使用 secrets。
- collections.deque 适合双端队列,Counter 适合计数,defaultdict 可按工厂创建缺省值。
- heapq 实现最小堆,bisect 在已排序序列中二分定位,itertools 提供高效迭代组合工具。
- if __name__ == '__main__': 用来区分文件被直接运行还是被导入。
常见误区
- 文件名写成 math.py 导致遮蔽标准库
- import * 污染命名空间
- 把 random 当成加密随机数
- 没有理解工具的数据复杂度就盲目调用
适用边界
- 标准库非常大,本章覆盖课程会实际依赖的入口;具体函数签名应结合本站条目与运行时帮助查询。
- Turtle 需要图形窗口,本站文本判题环境不伪造其画布。
完成检查