前言
程序有三大结构:顺序、循环和选择。貌似有数学家给出了证明,任何一件复杂的事都是由这三种结构组成的。
拿我们的人生举例,每个人都要经历从出生到死亡的顺序结构,在短暂的生命里总是会重复(循环)做同一件事,上学、工作等等,同时我们也面临着许多选择,每一个选择或多或少决定着人生的走向。
从这点来说的话,程序甚至可以模拟人生。
言归正传,今天给大家介绍一下新的结构——选择结构。
1. 简单示例
首先呢,我们来一起见识一下 Python 中选择结构大体是怎么肥事。
下面是一个简单的示例,演示了如何使用 if
语句来正确地处理特殊情况。
假设你班 韩雷雷 同学因为生病导致班主任点名的时候没有喊'到'。
students = ['李春梅', '张翠花', '李狗蛋', '韩雷雷', '孔小乙']
for student in students:
if student == '韩雷雷':
print('班主任:', '韩雷雷', '无人回应')
else:
print('班主任:', student + ';', student + ':', '到')
这个示例中的循环首先检查当前学生是不是 韩雷雷。如果是,就打印 无人回应;否则就打印 到。
结果如图1-1:
下面正式进入今天的主题。
2. 布尔表达式
要想看懂并学会 if
语句,不会布尔表达式可不行。
2.1 什么是布尔表达式?
布尔表达式(Boolean expression)是一段代码声明,它最终只有true(真)和false(假)两个取值。最简单的布尔表达式是等式(equality),这种布尔表达式用来测试一个值是否与另一个值相同。—— 百度百科
想想还是引用下正式的解释比较高大上。
解释环节:
布尔表达式是一段代码声明,有人可能对 一段代码声明 有点犯晕,简单地理解成一段代码就行。
不管布尔表达式或长或短或简单或复杂,运行结果只有 true(真)
和 false(假)
两个取值。
为什么说布尔表达式对 if
条件选择语句这么重要呢?因为上面我们举的点名例子中 if
语句后面跟着的 student == '韩雷雷'
就是布尔表达式,很巧地是这个表达式也是百度百科定义中提到地最简单的布尔表达式——等式。
2.2 检查是否相等
我们从最简单的布尔表达式开始,前面提到,最简单的布尔表达式是等式,因为 =(等号)
已经被用来作赋值运算符,所以判断是否相等的等式运算符我们用 ==(两个等号)
。
>>> name = 'Kelvin'
>>> name == 'Kelvin'
True
我们首先使用一个等号将 name
的值设置为 'Kelvin',这种做法你应该见过很多次了。
接下来,使用两个等号检查 name
的值是否为 'Kelvin'。这个相等运算符在它左右两边的值相等时返回 True
,否则返回 False
, 顺便提一句, Python 里真假分别是 True/False
,在其他语言里有的用的是全小写,这个要注意。
在这个示例中,==
两边的值相等,因此 Python 返回 True
。
如果变量 name
的值不是 'Kelvin', 上述测试将返回 False
:
>>> name = 'Vicky'
>>> name == 'Kelvin'
False
一个等号是陈述,对于第一行代码,可解读为 将变量 name 的值设置为 'Vicky'。
两个等号是发问,对于第二行代码,可解读为 变量 name 的值是 'Kelvin' 吗?。
2.3 检查是否不相等
要判断两个值是否不相等,可结合使用惊叹号和等号(!=
),其中的惊叹号表示 非,在很多编程语言中都是如此。
假设韩雷雷身体康复回到了班级,下课时间,班上同学哈哈啊哈的聊天,只有 孔小乙 同学在认真学习。也就是说,除了 孔小乙 同学,别的同学都在哈哈哈。
我们用代码记录了这一刻:
students = ['李春梅', '张翠花', '李狗蛋', '韩雷雷', '孔小乙']
for student in students:
if student != '孔小乙':
print(student + ': ', '哈哈啊哈')
循环班级同学的名字,如果不是 孔小乙 就 哈哈啊哈。
运行这段代码,结果如图2-1:
可以看到课间就只有 孔小乙 同学仍在好好学习天天向上。
2.4 比较数字
检查数值非常简单,例如,检查 李狗蛋 同学的数学成绩:
>>> grade = 60
>>> grade == 60
True
李狗蛋 同学的成绩刚好60分,所以返回 True
。
除此之外还能进行不相等的检查,例如判断 李狗蛋 的成绩不等于90分:
>>> grade = 60
>>> grade != 90
True
因为 狗蛋 的成绩确实不等于90分,所以返回的还是 True
,非常符合逻辑。
学数学的时候我们除了可以比较两个数字等于或不等,还可以判断是不是大于、小于、大于等于和小于等于。Python 肥肠贴心地给我们提供了这些判断符号。
>>> grade = 60
>>> grade < 60
False
>>> grade <= 60
True
>>> grade > 60
False
>>> grade >= 60
True
这些比较符的运用和我们数学上的含义是一样的。
2.5 检查多个条件
你可能想同时检查多个条件,例如,有时候你需要在两个条件都为 True
时才执行相应的操作,而有时候你只要求一个条件为 True
时就执行相应的操作。
由此引入了关键字 and
和 or
。
2.5.1 关键字 and
如果你熟悉逻辑运算的概念,那么 and
指的是逻辑与运算。
不熟悉也没有关系,以两个条件为例,我粗略地做了张表:
p | q | p and q |
---|---|---|
True | True | True |
True | False | False |
False | True | False |
False | False | False |
and 关键字的特点是:只有左右两边条件都为 True 时,结果才为 True,否则都是 False。
例如,要检查两个同学的年龄是否都不小于 16 岁,代码如下:
>>> age_0 = 18
>>> age_1 = 14
>>> age_0 >= 16 and age_1 >= 16
False
>>> age_1 = 20
>>> age_0 >= 16 and age_1 >= 16
True
我们先定义了两个变量 age_0
和 age_1
来存储年龄。
age_0 >= 16 and age_1 >= 16
这种写法其实和 (age_0 >= 16) and (age_1 >= 16)
等价的。先判断 age_0 >= 16
,因为 age_0
的值是18,所以满足条件,返回的是True
,然后判断age_1 >= 16
,因为age_1
的值是14,所以不满足条件,返回的是 False
,最后and
运算符左边的是 True
,右边的是 False
,类似这样 True and False
,根据and
关系表格可知,结果是 False
。
然后我们修改了第二个学生的年龄:age_1 = 20
,再次进行 and
运算时,由于age_1
的值现在是20,所以满足条件,返回的也是 True
,类似这样 True and True
,根据 and
关系表格可知,结果是 True
。
因此 and
运算也可以总结为:只要有一个条件不满足,整个布尔表达式就为 False。
2.5.2 关键字 or
如果你熟悉逻辑运算概念,那么 or
指的是逻辑或运算。
同样地,不熟悉也没关系,以两个条件为例,我粗略地做了张表:
p | q | p or q |
---|---|---|
True | True | True |
True | False | True |
False | True | True |
False | False | False |
or 关键字的特点是:只有左右两个条件都为 False时,结果才为 False,否则都是 True
下面再次检查两位同学的年龄,条件是至少有一个人的年龄不小于16岁,代码如下:
>>> age_0 = 18
>>> age_1 = 14
>>> age_0 >= 16 or age_1 >= 16
True
>>> age_0 = 15
>>> age_0 >= 16 or age_1 >= 16
False
我们先定义了两个变量 age_0
和 age_1
来存储年龄。
age_0 >= 16 or age_1 >= 16
这种写法其实和 (age_0 >= 16) or (age_1 >= 16)
等价的。先判断 age_0 >= 16
,因为 age_0
的值是18,所以满足条件,返回的是True
,然后判断age_1 >= 16
,因为age_1
的值是14,所以不满足条件,返回的是 False
,最后and
运算符左边的是 True
,右边的是 False
,类似这样 True or False
,根据or
关系表格可知,结果是 True
。
然后我们修改了第一个学生的年龄:age_0 = 15
,再次进行 or
运算时,由于age_0
的值现在是15,所以不满足条件,返回的也是 False
,类似这样 False or False
,根据 or
关系表格可知,结果是 False
。
因此 or
运算也可以总结为:只要有一个条件满足,整个布尔表达式就为 True。
2.6 检查特定值是否包含在列表中
有时候,执行操作前必须检查列表是否包含特定的值。
要判断特定的值是否已包含在列表中,可使用关键字 in
。
下面代码,将检查 马冬梅 和 韩雷雷 是否包含在学生列表中:
>>> students = ['李春梅', '张翠花', '李狗蛋', '韩雷雷', '孔小乙']
>>> '马冬梅' in students
False
>>> '韩雷雷' in students
True
这个关键字很有用,可以轻松地检查列表中是否包含特定的值。
2.7 检查特定值是否不包含在列表中
还有的时候,需要确定特定的值未包含在列表中。
在这种情况下,可使用关键字 not in
。
下面代码,将检查 马冬梅 和 韩雷雷 是否不包含在学生列表中:
>>> students = ['李春梅', '张翠花', '李狗蛋', '韩雷雷', '孔小乙']
>>> '马冬梅' not in students
True
>>> '韩雷雷' not in students
False
可以看到,马冬梅 确实不包含在学生列表中,所以返回的是 True
,而 韩雷雷 包含在学生列表中,我们判断条件是不包含,所以返回的是 False
。
能坚持看到这里说明你对学习 Python 具有了起码的意志力,这些符号或许刚开始会让你眼花缭乱,更甚至你连逻辑运算也没有听说过。当你有这种感觉时,听我一句,实打实地在电脑上敲下这些代码,看看运行之后的效果,有些东西,你就不知不觉地掌握了。
3. if 语句
理解布尔表达式以后,就可以开始编写 if
语句了。
if
语句有很多种,选择使用哪种取决于要测试的条件数。
3.1 简单的 if 语句
本来想在这小节标题上加个最简单,后来想想,话说太满容易被杠就划掉了。
最简单的 if
语句只有一个简单的布尔表达式和一个操作:
if conditional_test:
do something
如果conditional_test
的结果为True
,Python 就会执行紧跟在 if
语句后面的代码;否则 Python 将忽略这些代码。
假设知道了某人的年龄,需要你判断这个人是否有选举投票权:
age = 19
if age >= 18:
print("你已经有资格参与选举投票啦!")
age >= 18
是个布尔表达式,判断 age
是否不小于18岁,age
的值是19,矮摆满足条件,因此 Python 执行缩进的 print
语句。
运行这段代码,结果如3-1:
在 if
语句中,缩进的作用与for
循环中相同。如果测试通过了,将执行 if
语句后面所有缩进的代码,否则将忽略它们。
在紧跟 if
语句后面的代码块中,可根据需要包含任意数量的代码行。
就拿刚刚判断某人年龄达不达到选举资格的例子:
age = 19
if age >= 18:
print("你已经有资格参与选举投票啦!")
print("啦啦啦~你是祖国的小红花~")
if
后面的布尔表达式为真,并且两条 print
语句都缩进了,因此他们都被执行了,效果如图3-2:
如果 age
的值小于18,这个程序将不会有任何输出。
3.2 if-else 语句
经常需要在布尔表达式为真时执行一系列操作,并在表达式为假时执行另一系列操作。
在这种情况下,可使用 Python 提供的 if-else
语句。
if-else
语句块类似于简单的 if
语句,但其中的 else
语句让你能够在表达式为假时执行一些操作。
假如,已知某人年龄,在其满足投票年龄时打印一些信息,若其不够投票年龄,也显示一条信息:
age = 17
if age >= 18:
print("你已经有资格参与选举投票啦!")
print("啦啦啦~你是祖国的小红花~")
else:
print("对不起,您太年轻了还不能参与投票")
print("未满18还是一枝花~")
如果 age >= 18
返回的是 True
,就执行第一个缩进的代码块;如果返回的是 False
,就执行 else
代码块。
这次 age
的值是17,布尔表达式返回是 False
,因此执行 else
代码块中的代码。
结果如图3-3:
上述代码之所以可行,是因为只存在两种情形:要么够投票年龄,要么不够。
if-else
非常适合用于要让 Python 执行两种操作之一的情形。
因为非此即彼,总是会执行两个操作中的一个。
辣么,如果存在三种及以上的选择情况咋办?下面介绍最复杂的 if
语句结构。
3.3 if-elif-else 语句
Python 只执行 if-elif-else
结构中的一个代码块,它依次检查每个表达式,直到遇到返回值为真的表达式,然后 Python 将执行紧跟在它后面的代码,并跳过余下的代码块。
例如,来看个景点收费的标准:
4岁以下免费;
4~18岁收费30元;
18岁(含)以上收费60元。
如果只使用一条 if
语句,我们貌似也可以确定景点票价:
age = 12
if age < 4:
print("您可以免费进入景点")
if (age >= 4) and (age < 18):
print("您的票价是 30 元")
if age >= 18:
print("您的票价是 60 元")
我们先给 age
赋值为12;
然后 age
先和4进行比较,发现不满足条件,所以不执行 if age < 4
后面的代码块;
接着 age
和4、18比较,发现恰好同时满足大于等于4、小于18,因此执行 if (age >= 4) and (age < 18)
后面的代码块;
最后 age
和18进行比较,发现不满足条件,所以不执行 if age >= 18
后面的代码块。
所以,运行结果如图3-4:
果然如我们分析的那样,执行了第二个 if
语句后面的代码块。
不知道你们发现没有,像上面这种写法,不管游客年龄如何,都需要比较3次。
下面我们来看看使用 if-elif-else
结构是如何写的:
age = 2
if age < 4:
print("您可以免费进入景点")
elif age < 18:
print("您的票价是 30 元")
else:
print("您的票价是 60 元")
我们先给 age
赋值为2;
然后 age
先和4进行比较,发现满足条件,所以执行了 if age < 4
后面的代码块;
最后,跳过余下的代码块。
看出区别了没:采用 if-elif-else 写法就比较了1次,代码执行效率上有了很大的提升。
当然也不是每次都只执行一次,就上述代码而言,一般在1~3次之间,所以效率上对比采用 if
语句写出的程序而言是很高的。
为了让代码优雅而不失简洁,可不在 if-elif-else
代码块中打印出门票价格,而只在其中设置门票价格,并在它后面添加一条简单的 print
语句:
age = 12
if age < 4:
price = 0
elif age < 18:
price = 30
else:
price = 60
print("您的门票价格是:" + str(price) + " 元")
在 if-elif-else
代码块中设置门票价格,最后在一条未缩进的 print
语句中根据设置的门票价格打印出一条消息。
这些代码的输出和前一个示例相同,但 if-elif-else
结构的作用更小,它只确定门票价格,而不是在确定门票价格的同时打印一条消息。除效率更高外,这些修订后的代码还更容易修改:要调整输出消息的内容,只需要修改一条而不是三条print
语句。
3.4 使用多个 elif 代码块
可根据需要使用任意数量的 elif
代码块。
例如,前述景点要给老年人打折,可再添加一个判断条件,判断游客是否符合打折条件。假设对于65岁(含)以上的老人,可以半价(即 30 元)购买门票:
age = 75
if age < 4:
price = 0
elif age < 18:
price = 30
elif age < 65:
price = 60
else:
price = 30
print("您的门票价格是:" + str(price) + " 元")
代码大体没变。第二个 elif
代码块通过检查确定年龄不到65岁后,才将票价设为最高票价(60 元)。当我们将年龄设为75时,程序会进入到 else
代码块并执行其中的代码。
结果你们也猜到了,猜不到的看图3-5:
3.5 省略 else 代码块
Python 并不要求 if-elif
结构后面一定要有 else
代码块。
在有些情况下,else
代码块很有用;而有些情况,去掉 else
语句意思表达的或许更清晰。
继续拿景点门票举例:
age = 75
if age < 4:
price = 0
elif age < 18:
price = 30
elif age < 65:
price = 60
elif age >= 65:
price = 30
print("您的门票价格是:" + str(price) + " 元")
最后一个 elif
代码块在游客年龄超过65(含)时,将价格设置为30元,这比我们使用 else
代码块更清晰些。
else
是一条神奇的语句,只要不满足任何 if
或 elif
中的布尔表达式,else
代码块中的代码就会执行。
结尾语
关于 if
语句还有些需要注意点,比如,变量为 None
怎么判断,if
语句的书写格式等等。但这些展开说的话篇幅就太长了,且不是重点,所以就省略啦(主要是怕你们看睡着)。
如果有谁精力旺盛想看的话,可以关注下面↓↓↓的微信公众号给我留言,或者有啥问题我们也可以相互讨论学习、共同进步。
最后,祝你学有所成。