选择与条件语句
引入| English | 释义 | 拼音 |
|---|---|---|
| condition/kənˈdɪʃn/ | 条件 | tiáo jiàn |
| selection/sɪˈlekʃn/ | 选择 | xuǎn zé |
为什么老人付了学生票价?
- 一家影院规定:儿童和 65 岁以上的人付 £5,学生付 £7,其他人付 £10。一位 70 岁的学生却被收了 £7。
- 程序里的每条规则都是对的,只是测试规则的顺序错了。这节课讲程序如何选择一条路,以及为什么顺序本身就是设计的一部分。
条件是一个“真或假”的问题
- **条件(condition)**是值为
bool的表达式:age >= 65、answer == "y"、n != 0。比较运算符有<、<=、>、>=、==(等于)和!=(不等于)。 - 用
and(两者都为真)、or(至少一个为真)和not(取反)组合条件。3 >= 3 and not (2 > 5)的值是True。
student = input("Student? y/n ") == "y" # already a bool
print(type(student)) # <class 'bool'>
print(3 >= 3 and not (2 > 5)) 显示什么?
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
3 >= 3 为 True;2 > 5 为 False,所以 not (2 > 5) 为 True。两边都为真,and 得到 True。
if 与 else:两条路走一条
if condition:只在条件为True时运行缩进的代码块;条件为False时运行else:代码块。两者恰好运行一个。- 缩进就是代码块。缩进在
if下面的行属于它;回到最左边的第一行无论如何都会运行。
if total >= 50:
fee = 0
else:
fee = 5
print("Delivery:", fee) # always runs
紧跟在 if 代码块后面、没有缩进的一行,只在条件为 True 时运行。
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
只有缩进的行属于 if。回到最左边的第一行在代码块之外,无论条件如何都会运行。
elif:第一个为真的分支胜出
- 用
if … elif … else做选择(selection)时,程序从上到下测试条件,只运行第一个为True的分支。其余分支全部跳过,即使它们也为真。 else接住剩下的所有情况,所以完整的链总是恰好走一条路。

某商店使用 if total >= 50: fee = 0,然后 elif total >= 20: fee = 3,然后 else: fee = 5。当 total 正好是 20 时,fee 是多少?
难度 2/5 · 今日首次完成可获 140 金币及少量额外奖励
20 >= 50 为 False,链条继续;20 >= 20 为 True,于是运行 fee = 3,跳过 else。边界值正是最值得测试的情况。
相信“落到下面”的含义
- 只有当上面所有测试都失败时,才会到达某个
elif。所以elif score >= 70不需要再写and score < 80:能走到这一行,就已经证明分数低于 80。 - 多写的测试让代码更长,而且每多一份,就多一个在边界上出错的机会。
if score >= 80:
band = "A"
elif score >= 70: # here score < 80 is already known
band = "B"
elif score >= 60:
band = "C"
else:
band = "F"
哪个分支会运行?
拖动分数,观察链条从上往下测试每个条件。只有第一个为真的分支会运行;在 79 分时,score >= 80 不成立,score >= 70 胜出。
在分级链中,为什么 elif score >= 70: 不需要写 and score < 80?
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
每个 elif 都继承了上面所有测试失败这一事实。80 分及以上的分数已经被第一个分支接住了。
把范围窄的规则放在前面
- 当两条规则可能同时为真时,写在前面的那条说了算。把必须胜出的规则(通常范围更窄)放在范围更宽的规则上面。
- 每条路各测一个输入,再测一个同时符合两条规则的输入。顺序错误就藏在这种重叠情况里。
- 儿童和 65 岁以上付 £5,学生付 £7,其他人付 £10。
- 先查年龄:
if age < 12 or age >= 65:,然后elif student:,然后else:。70 岁的学生付 £5。 - 先查学生:同一个人碰到
if student:,付 £7。两个程序都能通过“20 岁学生(£7)”和“30 岁成人(£10)”的测试,只有重叠情况才能看出差别。
把这些行排好顺序,使 70 岁的学生付 £5,20 岁的学生付 £7。
难度 3/5 · 今日首次完成可获 200 金币及少量额外奖励
在重叠情况下年龄规则必须胜出,所以先测试它。20 岁的学生年龄测试不成立,于是到达 elif student:。
小心地组合条件
- Python 允许连写比较:
0 <= mark <= 100表示0 <= mark and mark <= 100。 and一旦知道结果就停止计算。n != 0 and total / n > 5永远不会除以零,因为n为0时左边已经是False。
设 x = 15。哪些条件为 True?选出所有正确项。
难度 2/5 · 今日首次完成可获 140 金币及少量额外奖励
连写比较成立,而且 $15$ 是 5 的倍数。not x > 10 为 False。最后一项是陷阱:它表示 (x == 10) or 20,而 20 被当作真,所以对任何 x 都为真。
容易丢分的地方
- 在条件里写
=。if x = 5:是语法错误;比较要用==。 x == 1 or 2。 它的意思是(x == 1) or 2,而2被当作真,所以这个测试永远为真。应写x == 1 or x == 2,或x in (1, 2)。- 该用
elif却写了几个独立的if。 三个独立的if可能全部运行;elif链只运行一个。 - 边界。 用
>还是>=?要测试恰好在边界上的值,例如正好 70 分。
某程序有三个独立的语句:if score >= 60: print("C")、if score >= 70: print("B")、if score >= 80: print("A")。分数为 85 时它打印什么?
难度 1/5 · 今日首次完成可获 100 金币及少量额外奖励
每个独立的 if 都会被测试,所以三个都会运行。如果写成最高等级在前的 if … elif 链,只会打印 A。
你掌握了
- 条件是
bool表达式,由比较运算和and、or、not组成。 if … elif … else从上往下测试,只运行第一个为真的分支;else处理剩下的情况。- 每个
elif都已知道上面的测试失败了。顺序就是设计:把必须胜出的规则放在前面,并测试重叠情况和边界值。