目录
导入
在前面,我们学习了单向选择的if语句和多项选择的if-else语句。但是,在生活中N选1的情况更为多见。
在Python中,我们也可以添加更多的选择,来实现从"二选一"到"多选一"的进阶,一起来看看吧~

举个栗子
如图所示,为了实现完整的判断,我们使用了三个 if,来保证所有的得分对比情况(大于、等于、小于)都会有对应的输出。

代码优化
但是对于这种3个或以上的条件,无法使用一个if-else 结构来优化代码。这时可以使用Python判断语句中的第三个关键字 elif(else if的缩写)。

elif
if 后的语句是当 if 判断条件成立时,执行的操作。
elif 后的语句是当 if 判断不成立时,再判断一次,如果成立,执行的操作。
else 后的语句是当以上所有判断条件都不成立时,执行的操作。

栗子
本例第3、4行代码判断了如果变量 day 等于1,就输出"元气满满地工作"。第5、6行代码判断了如果变量 day 大于等于2并且小于等于5,就输出"继续搬砖吧"。第7、8行代码判断了如果之前的条件都不满足,就输出"世界这么大,出去走走吧"。
python
day = 3
if day == 1:
print("元气满满地工作")
elif (day >= 2) and (day <= 5):
print("继续搬砖吧")
else:
print("世界这么大,出去走走吧")
if判断
if后面的布尔表达式,在这里不成立。那么if后面的代码块,也就是第4行代码,不会被执行。

elif
是一个关键字,使else和if的缩写。如果之前的判断条件不成立,那么就重新做一次判断,执行elif后面的代码。

布尔表达式
两次比较运算,如果变量 day 大于等于2,如果变量 day 小于等于5。本例中结果都为True。一次逻辑运算 and("与"运算)。本例中参与运算的分别是 True 和 True ,运算结果为 True 。括号,用来框定代码运算的顺序,表明先进行比较运算,再进行逻辑"与"运算。

冒号
就像 if 和 else 一样,elif 语句的最后也需要一个冒号。在 elif 之后使用冒号,表示后续缩进的代码块在判断条件成立的时候会被执行。

缩进
缩进生成 elif 内的代码块,这里我们还是空四格。

else
一个关键字 else,如果前面的 if 和 elif 的判断条件都不成立,就执行 else 后面缩进的代码块。

执行顺序
情况一
我们把 if-elif-else 判断的执行顺序,梳理成流程图后,再来整理一下程序运行流程。第一种情况,程序运行到 if 判断时,如果条件为真,执行 if 的代码块。
完成后,运行 if-elif-else 后面的代码。

情况二
第二种情况,程序运行到 if 判断时,如果条件为假,程序就直接跳开 if 判断的执行部分,再次运行到 elif 的判断,如果条件为真,执行 elif 的代码块。
完成后,运行 if-elif-else 后面的代码。

情况三
第三种情况,程序运行到 elif 判断时,如果条件为假,程序就直接跳开 elif 判断的执行部分,运行 else 的代码块。
完成后,运行 if-elif-else 后面的代码。

if-elif-else特性
if-elif-else 语句有3个特性。
**1.**如果不满足 if 的条件,就判断是否满足 elif 的条件,满足就执行 elif 内的代码块,不满足就执行 else 内的代码块。
2. elif 需与 if 搭配使用,它无法独立出现。必须先有 if ,然后才能使用 elif ,否则程序就会报错。

**3.**if 、elif 与 else 成互斥关系。互斥关系指的是,程序不会同时执行 if 内、 elif 内和 else 内的代码块,只会执行其中一个。else 是把 if 和 elif 判断条件无法囊括的情况全部划分到自己这里。

三种判断语句小结
现在,我们已经学习了三种判断语句:if 、if-else 和 if-elif-else 。通过 if 、else 、elif 的搭配使用,我们可以覆盖条件判断中的所有情况,让程序按照我们预定的逻辑来执行很多自动化的工作。

if
if 语句属于单向判断。只要条件成立,就会运行 if 内的代码块;条件不成立,程序就会跳开 if 判断。

if-else
if-else 语句属于双向判断。如果 if 的条件不成立,就执行 else 内的代码块。if 和 else 是两个互斥关系,程序只会执行其中的一个。

if-elif-else
if-elif-else 语句属于多向判断 (3个或以上的条件)。
如果 if 的条件不成立,就执行 elif 再判断一次,如果 elif 的条件也不成立,就执行 else 内的代码块。
if 、elif 、 else 是互斥关系,程序只会执行其中的一个 。
并且,当判断的条件超过3个时,中间的多个条件都可以使用 elif ,无论中间有多少个 elif ,它和其他 if 、elif 都是互斥关系。

嵌套语句
之前的博文中,处理的判断条件都是独立的,不存在条件之中还有条件的情况。但是正如生活的选择题往往没有那么简单一样,在Python中也常会遇到判断条件继续细分的情况。
对于这种在条件成立的基础上又不断细分出其他条件的情况,称为嵌套。

定义 :嵌套是指将一个东西"套在"另一个东西里,就像套娃一样。同样的,嵌套语句是指将一个语句装在另一个语句里。

if嵌套
嵌套语句在很多地方都有应用,今天咱们主要学习 if 的嵌套。
if 嵌套 :
在基础条件满足的情况下,再在基础条件里面增加额外的判断条件,即条件里套条件。
栗子
本例第1、2行代码分别将时间13和数量2赋值给了变量 time 和 num 。
第4、5行代码判断了如果变量 time 大于等于9并且小于等于23,就输出"在打折时间内"。
第7、8行代码在变量 time 大于等于9并且小于等于23成立的条件下,判断了如果变量 num 大于等于2,就输出"全场八折"。
python
time = 13
num = 2
if (time >= 9) and (time <= 23):
print("在打折时间内")
if num >= 2:
print("全场八折")

外层条件
第一层判断条件 if 。
首先判断了如果变量 time 大于等于9并且小于等于23,就输出"在打折时间内"。

内层条件
第二层判断条件 if 。
在第一层判断变量 time 大于等于9并且小于等于23成立的条件下,判断了如果变量 num 大于等于2,就输出"全场八折"。

缩进4格
Python是以缩进的空格数 来区分代码块的。
如果外层条件和内层条件的代码块都采用同样的缩进,Python 就没办法区分内外层条件是如何嵌套的。
在这里,外层条件 if 语句内的代码块缩进四个空格。

缩进8格
在将内层条件 if 语句写进外层条件的执行分支时,内层条件 if语句内的代码块要在原有缩进的基础上 ,再增加相应的缩进。
在这里,内层条件 if 语句内的代码块在外层条件内的代码块缩进的基础上再加四个空格,也就是八个空格。
注意⚠️ :缩进在Python语法规则中扮演重要的角色,千万不能忽视哦~

执行顺序
我们把 if 嵌套的执行顺序,梳理成流程图后,再来整理一下程序运行流程。
如图所示,嵌套的原则是先确定外层条件再确定内层条件,只有当外层条件成立时,才有可能进入到内层条件当中继续执行。

需要注意的是,在相互嵌套时,一定要严格遵守不同级别代码块的缩进规范。每嵌套一层都需要在原有缩进的基础上,再增加相应的缩进。

相互嵌套
不仅是 if 嵌套 ,在Python中,if 、if-else 和 if -elif-else 之间也可以相互嵌套。嵌套原则与 if 嵌套类似。
如图所示,这是一段能实现分组和判断成绩的代码。
1个外层条件 if-else 语句判断变量 gender 的值,确定男女分组,2个内层条件 if-else 语句判断变量 score 的值,确定成绩情况。

Tips
值得注意的是,虽然使用嵌套可以大大提高代码的逻辑性和层次感。但是,任何东西都不能过度使用。一般来说,超过3层以上的嵌套会使代码变得难以阅读,不符合Python简洁表达的理念。

Debug
博文的尾声,我们一起来梳理下,和判断语句相关的常见报错:
1. 语法错误
(1)忘记 if 、elif 、else 后的冒号:冒号常常被遗漏,这是判断语句的固定格式,有冒号程序才知道下面是谁的代码块。
(2)嵌套时,没有通过缩进来分层。在每层嵌套条件中需要额外再加四个空格。
第1个else没有缩进,导致第2个 else 找不到对应的 if 。

2. 缩进错误
if 、elif 、else 为互斥关系,其内部的代码块需要通过缩进形成。为了保持风格统一,每个缩进用四个空格。

总结
