第五章 if语句
5.1 一个简单示例
下面是一个简短的示例。假设你有一个汽车列表,并想将其中每辆汽车的名称打印出来。对于大多数汽车,应以首字母大写的方式打印其名称,但对汽车名’bmw’,应以全大写的方式打印。
下面的代码遍历这个列表,并以首字母大写的方式打印其中的汽车名,不过对于’bmw’,则以全大写的方式打印:
cars = ['audi','bmw','subaru','toyota']
for car in cars:
if car == 'bmw':
print(car.upper())
else:
print(car.tltle())
输出结果:
Audi
BMW
Subaru
Toyota
这个示例涵盖了本章将介绍的很多概念。下面先来介绍可用来在程序中检查条件的测试。
5.2 条件测试
每条if语句的核心都是一个值为True或False的表达式,这种表达式称为条件测试。Python根据条件测试的值为True或False来决定是否执行if语句中的代码。如果条件测试的值为True,python就执行紧跟在if语句后面的代码;如果为False,python就忽略这些代码。
5.2.1 检查是否相等
大多数条件测试将一个变量的当前值同特定值进行比较。最简单的条件测试检查变量的值与特定值是否相等:
>>>car = 'bmw'
>>>car == 'bmw'
True
首先使用一个等号将car的值设置为’bmw’,接下来使用两个等号检查car的值是否为’bmw’。这个相等运算符在两边的值相等时返回True,否则返回False。
5.2.2 检查是否相等时忽略大小写
在python中检查是否相等时区分大小写。例如两个大小写不同的值被视为不相等:
>>>car = 'Audi'
>>>car == 'audi'
False
如果大小写很重要,这种行为有其优点。但如果大小写无关紧要,只想检查变量的值,可将变量的值转换为小写,再进行比较:
>>>car = 'Audi'
>>>car.lower() == 'audi'
True
函数lower()不会修改最初赋给变量car的值,因此进行这样的比较不会影响原来的变量。
5.2.3 检查是否不相等
要判断两个值是否不相等,可使用惊叹号和等号(!=),其中的惊叹号表示不。
requested_topping = 'mushrooms'
if requested_topping != 'anchovies':
print('Hold the anchovies!')
5.2.4 数值比较
检查数值非常简单。条件语句中可以包含各种数学比较,如小于,小于等于,大于,大于等于:
>>>age = 19
>>>age == 19
True
>>>age < 21
True
>>>age <= 21
True
>>>age > 21
False
>>>age >= 21
False
5.2.5 检查多个条件
你可能想同时检查多个条件。例如有时需要在两个条件都为True时才执行相应的操作,而有时候只要求检查一个条件为True。在这些情况下,关键字and和or可以助你一臂之力。
- 使用and检查多个条件
要检查是否两个条件都为True,可使用关键字and将两个条件测试合而为一。如果每个测试通过了,整个表达式就为True;如果至少一个没通过,整个表达式就为False。
例如,要检查是否两个人都不小于21岁:
>>>age_0 = 22
>>>age_1 = 18
>>>age_0 >= 21 and age_1 >= 21
False
>>>age_1 = 22
>>>age_0 >= 21 and age_1 >= 21
True
为了改善可读性,可将每个测试分别放在一对圆括号内,但并非必须这样做。
(age_0 >= 21)and(age_1 >= 21)
- 使用or检查多个条件
关键字or只要至少有一个条件满足,就能通过整个测试。仅当两个测试都没通过,整个表达式才为False。
下面检查至少一个人的年龄不小于21岁:
>>>age_0 = 22
>>>age_1 = 18
>>>age_0 >= 21 or age_1 >= 21
True
>>>age_0 = 18
>>>age_0 >= 21 and age_1 >= 21
False
5.2.6 检查特定值是否包含在列表中
有时候执行操作前必须检查列表中是否包含特定的值。
要判断特定的值是否包含在列表中,可使用关键字in。下面来看看你可能为比萨店编写的一些代码。这些代码首先创建一个列表,其中包含用户点的比萨配料,然后检查特定的配料是否包含在列表中。
>>>requested_toppings = ['mushrooms','onions','pineapple']
>>>'mushrooms' in requested_toppings
True
>>>'pepperoni' in requested_toppings
False
5.2.7 检查特定值是否不包含在列表中
此时可使用关键字not in。
例如有一个列表包含禁止在论坛上发表评论的用户,可以在允许用户提交评论前检查其是否被禁言:
banned_users = ['andrew','carolina','david']
user = 'marie'
if user not in banned_users:
print(f"{user.title()},you can post a response if you wish.")
输出:
Marie,you can post a response if you wish.
5.2.8 布尔表达式
随着对编程的深入了解,将遇到布尔表达式,它不过是条件测试的别名。与条件表达式一样,布尔表达式的结果要么是True,要么是False。
布尔值通常用于记录条件,如游戏是否在运行,或者用户是否可以编辑网站的特定内容:
game_active = True
can_edit = False
在跟踪程序状态或程序中重要的条件方面,布尔值提供了一种高效的方式。
5.3 if语句
理解条件测试后,就可以开始编写if语句了。if语句有很多种,选择使用哪种取决于要测试的条件数。前面讨论条件测试时,列举了多个if语句示例,下面进一步讨论。
5.3.1 简单的if语句
最简单的if语句只有一个测试和一个操作:
if conditional_test:
do something
第一行可包含任务条件测试,而在紧跟在测试后面的缩进代码中,可执行任何操作。
假设有一个表示某人年龄的变量,而你想知道这个人是否符合投票的年龄,可使用:
age = 19
if age >= 18:
print("You are old enough to vote!")
输出:
You are old enough to vote!
在if语句中,缩进的作用与在for语句中相同。在紧跟if语句后面的代码块中,可根据需要包含任意数量的代码行。下面在一个人符合投票年龄时再打印一行输出,问他是否被登记了:
age = 19
if age >= 18:
print("You are old enough to vote!")
print("Have you registered to vote yet?")
如果age的值小于18,将不会有任何输出。
5.3.2 if-else语句
我们经常需要在条件测试通过时执行一个操作,在没有通过时执行另一个操作。此时可使用if-else语句。
下面的代码在一个人符合投票年龄时显示与前面相同的信息,在不符合时显示一条新消息:
age = 19
if age >= 18:
print("You are old enough to vote!")
print("Have you registered to vote yet?")
else:
print("Sorry, you are too young to vote.")
print("Please register to vote as soon as you turn 18!")
5.3.3 if-elif-else结构
我们经常需要检查超过两个的情形,为此可使用if-elif-else结构。Python只执行if-elif-else结构中的一个代码块。它依次检查每个条件测试。测试通过后,python将执行紧跟在它后面的代码,并跳过剩下的测试。
在现实中,很多情况需要考虑的情形超过两个。例如,来看一个根据年龄段收费的游乐场:
- 4岁以下免费
- 4~18岁收费25美元
- 18岁(含)以上收费40美元
如果只使用一条if语句,下面的代码确定一个人所属的年龄段,并打印一条包含门票价格的消息:
age = 12
if age < 4:
print("Your admission cost is $0.")
elif age < 18:
print("Your admission cost is $25.")
else:
print("Your admission cost is $40.")
输出:
Your admission cost is $25.
为了让代码更简洁,可不在if-elif-else代码块中打印门票价格,而在其中设置门票价格,并在最后添加一个简单的函数调用print( ):
age = 12
if age < 4:
price = 0
elif age < 18:
price = 25
else:
price = 40
print(f"Your admission cost is ${price}.")
5.3.4 使用多个elif代码块
可根据需要使用任意数量的elif代码块。
age = 12
if age < 4:
price = 0
elif age < 18:
price = 25
elif age < 65:
price = 40
else:
price = 20
print(f"Your admission cost is ${price}.")
5.3.5 省略else代码块
Python并不要求if-elif结构后必须有else代码块。有时候else代码块很有用;而有时候使用一条elif语句来处理特定的情形更清晰:
age = 12
if age < 4:
price = 0
elif age < 18:
price = 25
elif age < 65:
price = 40
elif age >= 65:
price = 20
print(f"Your admission cost is ${price}.")
else是一条包罗万象的语句,只要不满足任务if或elif中的条件测试,其中的代码就会执行。这可能引入无效甚至恶意的数据。如果知道最终要测试的条件,应考虑使用一个elif代码块来代替else代码块。这样就可以肯定,仅当满足相应的条件时,代码才会执行。
5.3.6 测试多个条件
if-elif-else结构功能过于强大,但仅适合用于只有一个条件满足的情况:遇到通过了的测试后,python就跳过剩下的测试。这种行为很好,效率很高,让你能够测试一个特定的条件。
然而,有时必须检查你关心的所有条件。此时应使用一系列不包含elif和else代码块的简单if语句。在可能有多个条件为True且需要在每个条件为True时都采取相应的措施时,适合使用这种方法。
下面再来看看比萨店示例。如果顾客点了两种配料,就需要确保其在比萨中包含这些配料:
requested_toppings = ['mushrooms','extra cheese']
if 'mushrooms' in requested_toppings:
print("Adding mushrooms.")
if 'pepperoni' in requested_toppings:
print("Adding pepperoni.")
if 'extra cheese' in requested_toppings:
print("Adding extra cheese.")
print("\nFinished making your pizza!")
输出:
Adding mushrooms.
Adding extra cheese.
Finished making your pizza!
如果使用if-elif-else结构,代码将不能正确运行,因为有一个测试通过后,就会跳过余下的测试。总之,如果只想执行一个代码块,就使用if-elif-else结构;如果执行多个代码块,就使用一系列独立的if语句。
5.4 使用if语句处理列表
通过结合使用if语句的列表,可完成许多任务:对列表中特定的值做特殊处理;高效管理不断变化的情形。
5.4.1 检查特殊元素
下面研究如何检查列表中的特殊值,并对其做合适的处理。
继续使用前面比萨店示例。这家比萨店在制作比萨时,每添加一种配料都打印一条消息。通过创建一个列表,在其中包含顾客点的配料,并使用一个循环来指出添加到比萨中的配料,能以极高的效率编写这样的代码:
requested_toppings = ['mushrooms','green peppers','extra cheese']
for requested_topping in requested_toppings:
print(f"Adding {requested_topping}.")
print("\nFinished making your pizza!")
输出很简单:
Adding mushrooms.
Adding green peppers.
Adding extra cheese.
Finished making your pizza!
然而如果比萨店的青椒用完了,为妥善处理,可在for循环中包含一条if语句:
requested_toppings = ['mushrooms','green peppers','extra cheese']
for requested_topping in requested_toppings:
if requested_topping == 'green peppers':
print("Sorry,we are out of green peppers right now.")
else:
print(f"Adding {requested_topping}.")
print("\nFinished making your pizza!")
输出:
Adding mushrooms.
Sorry,we are out of green peppers right now.
Adding extra cheese.
Finished making your pizza!
5.4.2 确保列表不是空的
到目前为止,我们对处理的每个列表都做了个简单的假设——假设它们都至少包含一个元素。因为马上就要让用户来提供存储在列表中的信息,所以不能再假设循环运行时列表不是空的。鉴于此,在运行for循环前确定列表是否为空很重要。
下面在制作比萨前检查顾客点的配料列表是否为空。如果列表为空,就像顾客确认是否要点原味比萨;如果不为空,就像前面那样制作比萨:
requested_toppings = []
if requested_toppings:
for requested_topping in requested_toppings:
print(f"Adding {requested_topping}.")
print("\nFinished making your pizza!")
else:
print("Are you sure you want a plain pizza?")
首先创建了一个空列表,随后进行检查,而不是直接执行for循环。在if语句中将列表名用作条件表达式时,Python将在列表至少包含一个元素(不为空)时返回True,并在列表为空时返回False。
输出:
Are you sure you want a plain pizza?
5.4.3 使用多个列表
顾客的要求往往五花八门,在比萨配料方面也是如此。如果顾客要在比萨中添加炸薯条,该怎么办?可使用列表和if语句来确定能否满足顾客的要求。
来看看在制作比萨前如何拒绝怪异的配料要求。下面的示例定义了两个列表,其中第一个列表包含比萨店供应的配料,而第二个列表包含顾客点的配料。这次对于requested_toppings中的每个元素,都检查它是否是比萨店供应的配料,再决定是否在比萨中添加它:
available_toppings = ['mushrooms','olives','green peppers',
'pepperoni','pineapple','extra cheese']
requested_toppings = ['mushrooms','french fries','extra cheese']
for requested_topping in requested_toppings:
if requested_topping in available_toppings:
print(f"Adding {requested_topping}.")
else:
print(f"Sorry,we don't have {requested_topping}.")
print("\nFinished making your pizza!")
输出结果:
Adding mushrooms.
Sorry,we don't have french fries.
Adding extra cheese.
Finished making your pizza!
5.5 设置if语句的格式
本章的每个示例都展示了良好的格式设置习惯。在条件测试的格式设置方面,PEP 8提供的唯一建议是,在诸如==、>=和<=等比较运算符两边各添加一个空格。例如:
if age <= 4
要比
if age<=4
更好。