
3.2 选择结构
分支结构可以分为单分支结构和多分支结构,用于解决生活中形形色色的选择问题。比如,驾驶员理论考试科目中,成绩达到90分的为合格。
选择结构语句也称为条件判断语句,即按照条件选择执行不同的代码片段。Python中的选择语句主要有3种形式,分别为if语句、if…else语句和if…elif…else多分支语句。
在其他语言中(例如,C、C++、Java等),选择语句还包括switch语句,也可以实现多重选择。但是,在Python中没有switch语句,所以实现多重选择的功能时,只能使用if…elif…else多分支语句或者if语句的嵌套。
3.2.1 if语句
Python中使用if保留字来组成选择语句。if语句仅处理条件成立的情况,其流程如图3-2所示。从图中可以看出,当表达式的值为真时,执行相应的语句块(一条或多条语句):当表达式的值为假时,直接跳出if语句,执行其后面的语句。
if语句的书写格式为:

其中,表达式可以是一个单纯的布尔值或变量,也可以是比较表达式或逻辑表达式(例如,a﹥b and a!=c),如果表达式为真,则执行“语句块”;如果表达式为假,就跳过“语句块”,继续执行后面的语句。这种形式的if语句相当于汉语里的关联词语“如果……就……”。
关键字if与表达式之间用空格隔开,表达式后接英文冒号,语句块中的全部语句均缩进4个空格,如图3-3所示。
【例3-3】 输入姓名和年龄,判断是否为成年人。


图3-2 单分支结构流程图

图3-3 单分支结构书写格式
运行结果:

使用if语句时,如果只有一条语句,语句块可以直接写到“:”的右侧,例如,“if a﹥b:max=a”。但是,为了程序代码的可读性,建议不要这么做。
if语句使用过程中的常见错误如下。
1)if语句后面未加冒号。
2)使用if语句时,如果在符合条件时,需要执行多个语句,但是,在第二个输出语句的位置没有缩进。
3.2.2 if…else语句
如果遇到只能二选一的条件,例如,大学毕业是直接就业还是考研深造?Python中提供了if…else语句解决类似问题,其语法格式如下。

使用if…else语句时,表达式可以是一个单纯的布尔值或变量,也可以是比较表达式或逻辑表达式,如果满足条件,则执行if后面的语句块,否则,执行else后面的语句块,这种形式的选择语句相当于汉语里的关联词语“如果……否则……”。
【例3-4】 询问年龄,如果年龄大于或等于18岁,输出“你今年成年了”,如果小于18岁,输出“还差几岁才能够成年”。

运行结果:

【例3-5】 编写程序,从键盘输入三条边,判断是否能够构成一个三角形。如果能,则提示可以构成三角形;如果不能,则提示不能构成三角形。
分析:组成三角形的条件是任意两边之和大于第三边,如果条件成立,则能构成三角形;当条件表达式中的多个条件必须全部成立时,条件之间可用and运算符连接起来。

运行结果:

3.2.3 if…elif…else语句
if…elif…else语句主要用于处理多种条件的情况,从而解决现实生活中复杂的多重选择问题,其流程如图3-4所示。
使用if…elif…else语句时,表达式可以是一个单纯的布尔值或变量,也可以是比较表达式或逻辑表达式,如果表达式为真,执行语句;而如果表达式为假,则跳过该语句,进行下一个elif的判断,只有在所有表达式都为假的情况下,才会执行else中的语句。
如果表达式1的值为真,则执行相应的语句块A;如果表达式1的值为假,则继续判断表达式2的值,如果表达式2的值为真,则执行语句块B;如果表达式2的值也为假,则继续判断表达式3的值;其余类推,直到所有的表达式都不满足(条件表达式的个数为1个或多个)为止,然后执行else后面的语句块。
书写格式:关键字if与表达式1之间用空格隔开,表达式1后接英文冒号;所有关键字elif均与关键字if左对齐,elif与后面的各个表达式之间用空格隔开,表达式后接英文冒号;关键字else与关键字if左对齐,后接英文冒号;所有语句块左对齐,即所有语句块中的全部语句均缩进4个空格,如图3-5所示。

图3-4 多分支结构流程图

图3-5 多分支结构书写格式
【例3-6】 输入学生姓名,以及语文、数学、英语三门课的成绩,判断能够获几等奖。

运行结果:

如果只考虑一种表达式成立或不成立的结果(即没有elif分支),则多分支的if结构转化为双分支的if结构。
在使用分支结构时,需要注意以下事项。
1)表达式可以是任意类型,如5﹥3,x and y﹥z,3,0等。其中,3表示恒真(即True),而0表示恒假(即False)。
2)可以仅有if子句构成单分支结构,但是else子句必须与if子句配对,不能出现仅有else子句没有if子句的情况。
3)各语句块可以是一条或多条语句,如果是多条语句,则所有语句必须左对齐。
【例3-7】 编写程序,判断合法工作年龄(为18-60岁),即如果年龄小于18的情况为童工,不合法;如果年龄在18-60岁之间为合法工龄;大于60岁为法定退休年龄。

运行结果:

【例3-8】 编写程序,调用随机函数生成一个1~100之间的随机整数,从键盘输入数字进行猜谜,给出猜测结果(太大、太小、成功)的提示。
分析:通过引入random模块,可以调用其中的randint(a,b)函数产生介于a和b之间的随机整数(即产生的随机数大于等于a且小于等于b),然后从键盘输入一个数字与该随机数进行比较,并输出判断结果。

运行结果:

3.2.4 分支语句嵌套
当有多个条件需要满足并且条件之间有递进关系时,可以使用分支语句的嵌套。其中,if子句、elif子句以及else子句中都可以嵌套if语句或者if…elif…else子句。
书写格式:嵌套的if语句要求以锯齿形缩进格式书写,以便分清层次关系。
【例3-9】 我国的婚姻法规定,男性22岁为合法结婚年龄,女性20岁为合法结婚年龄。因此如果要判断一个人是否到了合法结婚年龄,首先需要使用双分支结构判断性别,再用递进的双分支结构判断年龄,并输出判断结果。

运行结果:

【例3-10】 编写程序,从键盘输入用户名和密码,要求先判断用户名再判断密码,如果用户名不正确,则直接提示用户名输入有误;如果用户名正确,则进一步判断密码,并给出判断结果的提示。
分析:因为要求先判断用户名再判断密码,所以本程序的一种做法是使用if语句的嵌套,外层if语句用于判断用户名,用户名正确时进入内层if语句判断密码并给出判断结果,如果用户名不正确,则直接给出错误提示。

运行结果:

【例3-11】 编写程序,开发一个小型计算器,从键盘输入两个数字和一个运算符,根据运算符(+、—、*、/)进行相应的数学运算,如果不是这4种运算符,则给出错误提示。
分析:因为需要根据4种运算符号的类别执行相应的运算,所以使用多分支if…elif…else语句;对于除法运算而言,由于除数不能为0,因此需要使用嵌套的if语句来判断除数是否为0,并执行相应的运算。


运行结果:

if选择语句可以有多种嵌套方式,开发程序时可以根据自身需要选择合适的嵌套方式,但一定要严格控制好不同级别代码块的缩进量。