学径 LearnPath

编程语言基础

选择

在分岔处进行判断。

讲解模式

通过本节课,你将理解:

#goal

程序不仅要能自上向下的逐行执行,也要能够在某些时候选择是否执行或者跳过某些行。

在Python里,这被称作 选择结构,通过 if / elif / else 和缩进 来描述。

本节课你将学会:如何写出选择结构,以及理解进入子结构的判断条件。

执行程序的条件

#hook

在地铁站,当乘客把卡贴在进站闸机上之后,机器里的程序需要先判断是哪一种情景,再决定下一步怎么处理:

  • 卡无法识别:闸门保持关闭,屏幕提示车票无效。
  • 卡可以识别,但余额不够本次车费:闸门仍然关闭,提示余额不足。
  • 卡可以识别,并且余额足够:扣除车费,打开闸门。
地铁进站闸机的流程图:菱形是判断,矩形是处理
地铁进站闸机的流程图。菱形表示判断,矩形表示处理;「是」与「否」各自通向一条路,程序只进入其中一条。

这就是一个典型具有选择结构的程序:流程图中的菱形步骤,发起一次判断,程序在这个位置将根据情况来选择接下来要前往路线。

芬兰奥卢的铁路道岔
芬兰奥卢的手动铁路道岔。TeVe。来源:Wikimedia Commons,公有领域。

不论选择走哪边,列车只能运行在一条轨道上。

如果...才能...

#explore-if

在Python里, 我们可以使用 if 来标记一个最简单的选择结构,表示如果xxx条件成立,才能进行xxx动作,主要用于在特定条件下跳过某些行。

python
# 求number的绝对值
number = 1 # 试着修改number的值为负数,看看输出
if number < 0:
    number = -number # 如果number<0,就让它的值改为相反数
print(number)

if所在的这一行应有一次逻辑运算,表示判断条件,并以冒号结束,下方用缩进来标记它的子结构;当代码不再缩进,就表示已经不再属于子结构了。

在上方的代码中,if 后的判断条件为 number < 0,也就是说只有变量number值为负数时,才进行下面这行有缩进的 number = -number,即取相反数。

当 number 为 1 时,有缩进的这行代码将被跳过,但最后一行的 print 将被正确执行。

如果...否则...

#explore-else

如果选择的情况不是简单的跳过,而是要在两段代码中选择一段执行,那么我们可以使用if...else... 来表示这样的结构。即如果xxx条件成立进行动作a,否则进行动作b。

python
# 判断一个数是否能被7整除
number = 20 # 试着修改number的值为21
if number%7 == 0:
    print(number, '可以被7整除')
else:
    print(number, '不可以被7整除')

请注意这段代码的缩进结构,if 和 else 都是左侧对齐无缩进的,各自下方的代码分别进行缩进,表示各自的子结构。

在这段代码中,当 number = 20 时,会在 if 处进行判断,因为20模7的结果为6,不等于0,不满足此处判断条件,程序进入到 else 部分,执行对应的输出语句。

如果...否则如果...否则...

#explore-elif

如果有超过两种的分支的情况,还可以使用 elif 放在 if 和 else之间,表示如果xxx成立做动作a,否则如果yyy成立做动作b,否则做动作c。

python
# 根据分数评定等级
score = 65
if score >= 90:
    print('A')
elif score >= 75:
    print('B')
elif score >= 60:
    print('C')
else:
    print('D')

在变量 score 为 65时,程序在 if 先进行一次判断,不满足 score>=90 的条件。跳到下一个 elif 处,也不满足 score>=75 的条件。再到下一个 elif 处,这时满足此处的 score>=60 的条件,于是进行输出,结果为C。

if的嵌套

#explore-nest

选择结构中的每个子结构,也是一段程序,当然也可以有子结构的子结构,称作代码嵌套。

python
# 求一元一次方程ax+b=0的解
a = 0
b = 1
if a == 0:
    if b == 0:
        print('有无数解')
    else:
        print('无解')
else:
    print(-b/a)

变量a的值为0,于是在if处进入了子结构。子结构中又有一组选择,因为变量b的值为1,在这组选择中,程序最终进入到打印无解的步骤中,完成输出。

复杂条件

#explore-logic

利用 and、or、not 可以把几个判断合成一个条件,避免过多的嵌套层级导致的缩进地狱。

比如上述求解一元一次方程的程序也可以改为:

python
a = 0
b = 1
if a == 0 and b == 0:
    print('有无数解')
elif a == 0:
    print('无解')
else:
    print(-b/a)

本节练习:土壤酸碱

#practice

在 在线 IDE 里用 if / elif / else 给土壤 pH 分类:小于 6.5 打印「偏酸」,小于等于 7.5 打印「近中性」,否则打印「偏碱」。给定三个读数,输出应当分别是:5.8 → 偏酸,7.0 → 近中性,8.2 → 偏碱。

本节要点

#review
  • 选择结构在判断处选路。条件成立,才执行缩进的子结构;与 if 对齐的语句不在这条路上。
  • 两种情形用 if...else...。更多情形用 elif:前面的条件已经成立,后面的分支不再检查。
  • 代码嵌套是子结构里再写子结构。外层不成立,内层整块都被跳过,包括内层的 else。
  • and / or / not 把几个判断合成一个条件。能合成时,不必为每一问再套一层缩进。

单选题

缩进属于谁

运行后输出是?

number = 1
if number < 0:
    number = -number
print(number)

单选题

elif 的顺序

运行后输出是?

score = 65
if score >= 90:
    print('A')
elif score >= 75:
    print('B')
elif score >= 60:
    print('C')
else:
    print('D')

单选题

逻辑嵌套

运行后输出是?

a = 0
b = 1
print(a == 0 and b == 0)

多选题

关于选择结构

下列说法正确的有哪些?

可多选

单选题

嵌套与合成

求 ax+b=0。哪一段把「无数解」和「无解」分开,又没有再为 b 套一层 if?

未登录时不会保存学习进度