编程时经常需要检查一系列条件,并据此决定采取什么措施。在Python中,if 语句让你能够检查程序的当前状态,并采取相应的措施。
在本章中,你将学习条件测试,以检查所关心的任何条件。你将学习简单的if 语句,以及创建一系列复杂的if 语句来确定当前到底处于什么情形。接下来, 你将把学到的知识应用于列表,编写一个for 循环,以一种方式处理列表中的大多数元素,并以另一种方式处理包含特定值的元素。
5.1 一个简单示例
下面是一个简短的示例,演示了如何使用if 语句来正确地处理特殊情形。假设你有一个汽车列表,并想将其中每辆汽车的名称打印出来。对于大多数汽车,应以首字 母大写的方式打印其名称,但对于汽车名'bmw' ,应以全大写的方式打印。下面的代码遍历这个列表,并以首字母大写的方式打印其中的汽车名,不过对于'bmw' , 则以全大写的方式打印:
cars.py
cars = ['audi', 'bmw', 'subaru', 'toyota']
for car in cars:
if car == 'bmw':❶
print(car.upper())
else:
print(car.title())
这个示例中的循环首先检查当前的汽车名是否是'bmw' (见❶)。如果是,就以全大写方式打印,否则以首字母大写的方式打印:
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 。在本例中,两边的值相等,因此Python返回True 。
如果变量car 的值不是'bmw' ,上述测试将返回False :
>>> car = 'audi'❶
>>> car == 'bmw'❷
False
一个等号是陈述,于是❶处的代码可解读为:将变量car 的值设置为'audi' 。两个等号则是发问,于是❷处的代码可解读为:变量car 的值是'bmw' 吗?大多数编程语言使用等号的方式与这里演示的相同。
5.2.2 检查是否相等时忽略大小写
在Python中检查是否相等时区分大小写。例如,两个大小写不同的值被视为不相等:
>>> car = 'Audi'
>>> car == 'audi'
False
如果大小写很重要,这种行为有其优点。但如果大小写无关紧要,只想检查变量的值,可将变量的值转换为小写,再进行比较:
>>> car = 'Audi'
>>> car.lower() == 'audi'
True
无论值'Audi' 的大小写如何,上述测试都将返回True ,因为该测试不区分大小写。函数lower() 不会修改最初赋给变量car的值,因此进行这样的比较时不会影响原来的变量:
>>> car = 'Audi'❶
>>> car.lower() == 'audi'❷
True
>>> car❸
'Audi'
在❶处,将首字母大写的字符串'Audi'赋给变量car。在❷处,获取变量car的值并将其转换为小写,再将结果与字符串'audi'进行比较。这两个字符串相同, 因此Python返回True 。从❸处的输出可知,方法lower()并没有影响关联到变量car的值。
网站采用类似的方式让用户输入的数据符合特定的格式。例如,网站可能使用类似的测试来确保用户名是独一无二的,而并非只是与另一个用户名的大小写不同。用 户提交新的用户名时,将把它转换为小写,并与所有既有用户名的小写版本进行比 较。执行这种检查时,如果已经有用户名'john' (不管大小写如何),则用户提交用户名'John' 时将遭到拒绝。
5.2.3 检查是否不相等
要判断两个值是否不等,可结合使用惊叹号和等号(!= ),其中的惊叹号表示不,其他很多编程语言中也是如此。
下面再使用一条if 语句来演示如何使用不等运算符。我们将把要求的比萨配料赋给一个变量,再打印一条消息,指出顾客要求的配料是否是意式小银鱼(anchovies):
toppings.py
requested_topping = 'mushrooms'
if requested_topping != 'anchovies':
print("Hold the anchovies!")
❸处的代码行将requested_topping 的值与'anchovies' 进行比较。如果这两个值不相等,Python将返回True ,进而执行紧跟在if 语句后面的代码;如果相等,Python将返回False ,因此不执行紧跟在if 语句后面的代码。
因为requested_topping 的值不是'anchovies' ,所以执行函数调用print() :
Hold the anchovies!
你编写的大多数条件表达式检查两个值是否相等,但有时候检查两个值是否不等的效率更高。
5.2.4 数值比较
检查数值非常简单。例如,下面的代码检查一个人是否是18岁:
>>> age = 18
>>> age == 18
True
还可检查两个数是否不等。例如,下面的代码在提供的答案不正确时打印一条消息:
magic_number.py
answer = 17
if answer != 42:❶
print("That is not the correct answer. Please try again!")
answer 的值(17 )不是42 ,❶处的条件得到满足,因此缩进的代码块得以执行:
That is not the correct answer. Please try again!
条件语句中可包含各种数学比较,如小于、小于等于、大于、大于等于:
>>> age = 19
>>> age < 21
True
>>> age <= 21
True
>>> age > 21
False
>>> age >= 21
False
在if 语句中可使用各种数学比较,这让你能够直接检查关心的条件。
5.2.5 检查多个条件
你可能想同时检查多个条件。例如,有时候需要在两个条件都为True时才执行相应的操作,而有时候只要求一个条件为True。在这些情况下,关键字and和or可助你一臂之力。
a. 使用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 和age_1 。在❷处,检查这两个变量是否都大于或等于21。左边的测试通过了,但右边的测试没有通过,因 此整个条件表达式的结果为False 。在❸处,将age_1 改为22,这样age_1 的值大于21,因此两个测试都通过了,导致整个条件表达式的结果为True 。
为改善可读性,可将每个测试分别放在一对圆括号内,但并非必须这样做。如果你使用圆括号,测试将类似于下面这样:
(age_0 >= 21) and (age_1 >= 21)
b. 使用or检查多个条件
关键字or 也能够让你检查多个条件,但只要至少一个条件满足,就能通过整个测试。仅当两个测试都没有通过时,使用or 的表达式才为False 。
下面再次检查两个人的年龄,但检查的条件是至少一个人的年龄不小于21岁:
>>> age_0 = 22 ❶
>>> age_1 = 18
>>> age_0 >= 21 or age_1 >= 21 ❷
True
>>> age_0 = 18 ❸
>>> age_0 >= 21 or age_1 >= 21
False
同样,首先定义两个用于存储年龄的变量(见❶)。❷处对age_0的测试通过了,因此整个表达式的结果为True。接下来,将age_0减小为18。在❸处的测试中,两个测试都没有通过,因此整个表达式的结果为False 。
5.2.6 检查特定值是否包含在列表中
有时候,执行操作前必须检查列表是否包含特定的值。例如,结束用户的注册过程 前,可能需要检查他提供的用户名是否已包含在用户名列表中。在地图程序中,可能需要检查用户提交的位置是否包含在已知位置列表中。
要判断特定的值是否已包含在列表中,可使用关键字in 。下面来看看你可能为比萨店编写的一些代码。这些代码首先创建一个列表,其中包含用户点的比萨配料,然后检查特定的配料是否包含在该列表中。
>>> requested_toppings = ['mushrooms', 'onions', 'pineapple']
>>> 'mushrooms' in requested_toppings ❶
True
>>> 'pepperoni' in requested_toppings ❷
False
在❶处和❷处,关键字in 让Python 检查列表requested_toppings是否包含'mushrooms'和'pepperoni'。这种技术很有用,让你能够在创建一个列表后,轻松地检查其中是否包含特定的值。
5.2.7 检查特定值是否不包含在列表中
还有些时候,确定特定的值未包含在列表中很重要。在这种情况下,可使用关键字not in 。例如,有一个列表,其中包含被禁止在论坛上发表评论的用户,可以在允许用户提交评论前检查他是否被禁言:
banned_users.py
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.")
❶处的代码行明白易懂:如果user的值未包含在列表banned_users中,Python将返回True,进而执行缩进的代码行。
用户'marie'未包含在列表banned_users中,因此她将看到一条邀请她发表评论的消息:
Marie, you can post a response if you wish.
5.2.8 布尔表达式
随着你对编程的了解越来越深入,将遇到术语布尔表达式,它不过是条件测试的别名。与条件表达式一样,布尔表达式的结果要么为True,要么为False。
布尔值通常用于记录条件,如游戏是否正在运行,或者用户是否可以编辑网站的特定内容:
game_active = True
can_edit = False
在跟踪程序状态或程序中重要的条件方面,布尔值提供了一种高效的方式。
动手试一试
练习5-1:条件测试
编写一系列条件测试,将每个测试以及对其结果的预测和实际结果打印出来。你编写的代码应类似于下面这样:
car = 'subaru'
print("Is car == 'subaru'? I predict True.")
print(car == 'subaru')
print("\nIs car == 'audi'? I predict False.")
print(car == 'audi')
- 详细研究实际结果,直到你明白它为何为True或False。
- 创建至少10个测试,且其中结果分别为True和False的测试都至少有5个。
animal = 'fish'
print("Is animal == 'fish'? I predict True.")
print(animal == 'fish')
print("\nIs animal == 'bird'? I predict False." )
print(animal == 'bird')
练习5-2:更多条件测试
你并非只能创建10个测试。如果想尝试做更多比较,可再编写一些测试,并将它们加入conditional_tests.py中。对于下面列出的各种情况,至少编写两个结果分别为True 和False 的测试。
- 检查两个字符串相等和不等。
- 使用方法lower() 的测试。
- 涉及相等、不等、大于、小于、大于等于和小于等于的数值测试。
- 使用关键字and 和or 的测试。
- 测试特定的值是否包含在列表中。
- 测试特定的值是否未包含在列表中。
print('china' == 'China')
print("china" == 'CHINA'.lower())
print(3==2)
print(3!=2)
print(3>2)
print(3<2)
print(3>=2)
print(3<=2)
print(3>2 and 5<2)
print(3>2 and 5>2)
print(3>2 or 5<2)
print(3>2 or 5>2)
print(3 in [1,2,3,4,5,6])
print(3 not in [1,2,3,4,5,6])
print("3" in [1,2,3,4,5,6])
print("3" not in [1,2,3,4,5,6])