抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

image-20210617003312883

第七章 if条件判断

7.1 初识if语句

知识点:控制结构

到目前为止,Python程序都是按顺序流程,逐条语句执行。然而,顺序流程并不能解决所有问题。因此,需要改变程序的逻辑运行结构,来适应特定场景的需求

在现实中,很多场合都需要有选择的执行程序。例如,电梯需要根据用户的选择楼层来运行;空调需要根据设定模式来运行制冷或制热

Python提供了控制结构来实现上述功能。通过if条件判断语句,使程序可以根据条件来有选择地执行语句

7.1.1 判断的背景介绍

任务一:判断的定义

知识点:

如果 条件满足,才能做某件事情

如果 条件不满足,就做另外一件事情,或者什么也不做

正是因为有了判断,才使得程序世界丰富多彩,充满变化

判断语句 又被称为 “分支语句”,正是因为有了判断,才让程序有了很多的分支

7.1.2 if判断语句基本语法

任务一:BMI健康指数计算程序

知识点(背景介绍):BMI健康指数

BMI健康指数(BMI,Body Mass Index)是国际上常用的衡量人体肥胖程度和是否健康的重要标准。肥胖程度的判断不能采用体重的绝对值,它天然与身高有关。因此,BMI 通过人体体重和身高两个数值获得相对客观的参数,并用这个参数所处范围衡量身体质量

BMI=体重/身高的平方,单位:kg/㎡

目前,BMI健康指数的正常范围是18.5至24.9之间,这范围是比较健康的标准体重

BMI计算程序:根据的输入身高(m)和体重(kg)来计算BMI健康指数

1
2
3
4
5
6
7
8
9
10
11
12
# 定义BMI健康计算函数
def BMI_calc(weight, height):
BMI = weight / height**2
return BMI

# 输入身高和体重,要转换为浮点数
weight = float(input('输入体重(kg):'))
height = float(input('输入身高(m):'))

# 调用BMI计算函数
BMI = BMI_calc(weight, height)
print("BMI:{}, 体重:{}, 身高:{}".format(BMI, weight, height))

接下来,让程序变的聪明些,根据BMI值做出些判断。为实现上述功能,Python提供了if判断控制语句

任务二:if条件判断语句

Python 中,if 语句 就是用来进行判断的,格式如下:

1
2
if <condition>:
  <statement>

知识点:if语句由if :头部和缩进部分的****组成,具体如下:

if为判断的关键字。**:**为语句块标识符

判断条件,是一个值为TrueFalse的表达式

如果为True,执行紧跟在if语句后面的****语句块

如果为False,就**跳过**语句块

注意,if的语句块是否执行取决于条件是否满足

****:条件成立时,要做的事情

知识点:缩进的重要性

for循环类似,if语句块也使用缩进来标识语句块

一般缩进为一个 Tab 键,或者 4 个空格

建议,在**:之后敲回车,它之后的语句Jupyte**r会自动缩进

在 Python 开发中,Tab空格不要混用

任务三:判断年龄

需求分析:

定义一个整数变量记录年龄

判断是否满 18 岁 (**>=**)

如果满 18 岁,允许进网吧嗨皮

1
2
3
4
5
6
7
8
9
10
# 1. 定义年龄变量
age = 18

# 2. 判断是否满 18 岁
# if 语句以及缩进部分的代码是一个完整的代码块
if age >= 18:
print("可以进网吧嗨皮……")

# 3. 思考!- 无论条件是否满足都会执行
print("这句代码什么时候执行?")

知识点:

if 语句以及缩进部分是一个 完整的代码块

使用Jupyter代码折叠插件(左边的下三角),可以查看if语句的具体语句块范围

任务四:判断BMI健康程度

1
2
3
4
5
6
7
8
9
10
11
12
# 输入身高和体重,要转换为浮点数
weight = float(input('输入体重(kg):'))
height = float(input('输入身高(m):'))

# 调用BMI计算函数
BMI = BMI_calc(weight, height)
print("BMI:{}, 体重:{}, 身高:{}".format(BMI, weight, height))

if BMI < 18.5:
print('太苗条了!去吃顿大餐!')
if BMI > 24.9:
print('太重了!去操场思过吧!')

任务五:保留字True和False

知识点:

TrueFalse,为布尔类型``,是Python的保留字,代表逻辑真和假

truefalse为自定义的变量名,是“普通老百姓”

Python敏感于大小写。首字母大写的是保留字

为避免歧义,请尽量避免使用与关键字相似的词来命名变量

1
2
3
4
5
6
a = True
print(type(a), a)

#a是布尔类型,可以作为if判断条件
if a:
print('执行if')
1
2
3
4
5
6
7
# 小写的true是变量
true = False
print(type(true), true)

# 由于true变量是False,if不执行
if true:
print('执行if')

任务六:空列表、空字符串和数字零作为判断条件

知识点:

对于空列表**[]、空字符串“”‘’、数字0作为判断条件时,都判断为False**

但是字符串**’0’判断为True**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#False
condition = []
if condition:
print('True')

#False
condition = 0
if condition:
print('True')

#True
condition = '0'
if condition:
print('True')

7.1.3 if-else语句

任务一:掌握if-else语句

思考:在使用 if 判断时,只能做到满足条件时要做的事情。那如果需要在 不满足条件的时候,做某些事情,该如何做呢

答案:使用else处理条件不满足的情况,格式如下

1
2
3
4
if <condition>:
  <if statement>
else:
<else statement>

知识点:if-else语句实现2路分支

描述:当**判断条件为True,执行分支;不满足时,执行分支**

在if-else结构中,总是会执行两个操作中的一个

任务二:判断年龄的改进

需求分析:

输入用户年龄

判断是否满 18 岁 (**>=**)

如果满 18 岁,提示你成年了

如果未满 18 岁,提示你还是小屁孩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 输入用户年龄
age = int(input("今年多大了?"))

# 2. 判断是否满 18 岁
# if 语句以及缩进部分的代码是一个完整的语法块
if age >= 18:
print("你成年了")
print(":)")
else:
print("你还是小屁孩")
print(":(")

# 3. 思考!- 无论条件是否满足都会执行
print("这句代码什么时候执行?")

程序解析:

如果age >= 18条件为True,就执行if的语句块

如果为False,就执行else的语句块

由于age=17小于18,条件判断为False,因此执行else的语句块

知识点:

ifelse 语句以及各自的缩进部分是一个完整的if-else结构

习题:

题目要求:

  • 输入一个年份,判断当前是否是闰年,如果是则输出闰年,否则输出非闰年。(闰年条件:1. 能被4整除。2. 遇到100年,则需要被400整除)

代码如下:

1
2
3
4
5
year =eval(input("输入年份:")) # 2021
if(year % 4==0 and year % 100!=0) or year % 400==0:
print("闰年")
else:
print("非闰年")

运行结果:

1
非闰年

7.2 判断条件:布尔表达式

7.2.1 初识布尔表达式

任务一:初识布尔表达式(条件判断)

知识点(术语):判断条件或布尔表达式

布尔表达式语法:** **

描述:通过比较**两个表达式的值,返回结果是布尔值TrueFalse**

表达式的缩写。这里表达式可以是变量、运算结果、函数返回等

关系运算符的缩写

复杂的判断条件,可以通过逻辑运算符(and、or、not等)进行符合

Python 数学 含义
< < 小于
<= 小于等于
== = 等于
>= 大于等于
> > 大于
!= 不等于

与数学里不一样,Python使用**==表示逻辑相等,而=**表示赋值语句

知识点:布尔表达式

判断条件实际上是一种特殊的表达式,称为布尔表达式,为纪念乔治·布尔,一位19世纪英国数学家

对一个布尔表达式求值,会产生值True(条件成立)或False(不成立)

某些语言(C++)就用整数1和0来表示这些值。Java和Python有布尔表达式的专用数据类型bool

在Python中,布尔表达式类型为bool,布尔值由字面量TrueFalse表示

1
2
3
4
5
6
# 输出布尔表达式的结果
print(3 < 4)
print((3 * 4) < (3 + 4))
print("hello" == "hello")
print("hello" < "hello")
print("Hello" < "hello")

7.2.2 深入布尔表达式

任务一:==相等逻辑判断

知识点:

使用**==**来检查逻辑是否相等

对于int、float、bool、str数值和字符串类型,可以用**==**来判断两个变量的值是否相同

对于list、tuple等类型的变量(对象),并不能通过**==**来判断变量值是否相同

知识点(易错):

=是赋值。将变量设置为=右边的值。例如:a=1

==是逻辑相等的判断,结果为TrueFalse的布尔值。判断**==两边的变量是否相等。例如,a==b**

可以使用**=**赋值,将逻辑结果赋值给变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#对a和b进行赋值,然后使用a==b判断是否相等
a = 'LiLei'
b = 'LiLei'
print('{}=={}: {}'.format(a,b,a==b))

# 将a==b的结果赋值给res
res = a==b
# 建议加括号,避免出错
res = (a==b)
print(type(res), res)

a = 'LiLei'
b = 'LiLei'
# 将逻辑判断用于if判断
if a==b:
print('相等')

知识点:如果字符串的大小写无关紧要,而只想检查变量的值,可将字符串统一转换为小写,再比较

1
2
3
4
a = 'LiLei'
b = 'liLei'
res = (a.lower() == b.lower())
print(res)

统一大小写后,再作逻辑判断功能很实用

例如,网站可能使用类似的测试来确保用户名是独一无二的,使用上述的==逻辑判断并不能满足这一需求。因此,需要对用户注册的新用户名,首先将把它转换为小写,然后再与数据库中的名字进行比较。如果数据库中存在**’liLei’名字(不管大小写如何)时,则用户名‘LiLei’**系统会提示已经被注册

任务二:!=不等逻辑判断

知识点:要判断两个值是否不等,使用**!=(惊叹号和等号),其中的惊叹号表示不**

1
2
3
4
a = 'LiLei'
# 将!=逻辑判断用于if判断
if a!='liLei':
print('不相等')

代码解析:

a!=’liLei’a的值与字符串**’liLei’**进行比较

如果不相等,将返回True,并执行if语句块

如果这两个值相等,将返回False,不执行if语句块

由于a的值不是**’liLei’,因此执行if语句块print(),输出:不相等**

习题:

题目要求:

1、外部输入一个字符串,然后使用if检测当前字符串是否与预设的字符串相等

代码如下:

1
2
3
4
5
a = 'LiLei'
b = input("输入字符串:")
res = (a.lower() == b.lower())
print(res)
#a=4

运行结果:

1
false

题目要求:

2、外部输入一个数字,然后,检测当前的数字与预设的数字大小关系

代码如下:

1
2
3
4
a = '1'
b = input("输入数字:")
print('{}=={}: {}'.format(a,b,a==b))
#b=4

运行结果:

1
1==4: False

题目要求:

3、比较数字的1和字符串的“1”是否相等

1
2
3
a = '1'
b = '"1"'
print('{}=={}: {}'.format(a,b,a==b))

运行结果:

1
1=="1": False

任务三:字符串比较大小

知识点:字符串比较规则

按双字节Unicode码(类似于ASCII)的排序进行比较,大写字母都在小写字母之前。例如B排在a之前

从左到右的顺序,依次比较字符串中的字符,当出现相同字符时,就比较下个字符,直到结束

1
2
3
4
5
# 大写排小写之前
print('Lilei'>'lilei')

# 第1个字符串比第2个多了字符1
print('Lilei1'>'Lilei')

知识点:数字和字符串不能比较,出现TypeError

1
2
3
4
5
6
7
8
print('Lilei1' > 1)

# -----------------------------------------------------------
# TypeError Traceback (most recent call last)
# <ipython-input-85-bcc8908c4afd> in <module>
# ----> 1 print('Lilei1' > 1)

# TypeError: '>' not supported between instances of 'str' and 'int'
1
2
3
4
5
6
7
num = int(input('输入数字'))
if (1 <= num) and (num<=100):
print('哈哈,输入范围正确!')

print('-----在python中,可以作连续比较1 <= num <=100 ----')
if (1 <= num <=100):
print('哈哈,输入范围正确!')

7.2.3 逻辑运算符

任务一:逻辑运算符

知识点:使用逻辑运算符来复合多个表达式

在程序开发中,通常在判断条件时,会需要同时判断多个条件

在Python中,逻辑运算符and、or和not可以把多个简单的条件(布尔表达式)按照特定逻辑规则进行连接(组合),复合成更复杂的判断条件

知识点:

and:逻辑。只有所有布尔表达式都为True,结果才为True

or:逻辑。只要有一个布尔表达式为True,结果就为True

not:逻辑。如果是True,那么结果是False。反之亦然

为改善可读性,建议将每个布尔表达式分别放在**括号()**内

输入一个数字,判断当前数字是否在给定的范围**[1 100]区间之内**

1
2
3
num = int(input('输入数字:'))
if (1 <= num) and (num <= 100):
print('输入范围正确!')

知识点:为了避免复合表达式过于复杂,影响程序的阅读性,建议将复合表达式的结果赋值给临时变量

1
2
3
4
5
num = int(input('输入数字:'))
res = (1 <= num) and (num <= 100)
# 程序会变的简洁
if res:
print('输入范围正确!')

知识点:

Python专属,可以对数值类型的值作连续比较,省去and逻辑运算符

例如,判断数是否在**[1 100],可以使用1 <= num <=100**

1
2
3
num = int(input('输入数字:'))
if (1 <= num <= 100):
print('输入范围正确!')

输入一个数字,判断当前数字是否在给定的范围**[1 100]区间之外**

1
2
3
num = int(input('输入数字:'))
if (1 > num) or (num > 100):
print('输入范围正确!')

习题:

题目要求:

1、定义一个整数变量 age,编写代码判断年龄是否正确。要求人的年龄在 0-120 之间

1
2
3
4
5
age = 100
if age >= 0 and age <= 120:
print("年龄正确")
else:
print("年龄不正确")

运行结果:

1
年龄正确

题目要求:

2、定义两个整数变量 python_score、c_score,编写代码判断成绩。要求只要有一门成绩 > 60 分就算合格

1
2
3
4
5
6
python_score = 50
c_score = 50
if python_score > 60 or c_score > 60:
print("合格")
else:
print("不合格")

运行结果:

1
不合格

题目要求:

3、定义一个布尔型变量 is_employee,编写代码判断是否是本公司员工。如果不是提示不允许入内。提示:使用not运算符

1
2
3
is_employee = False
if not is_employee:
print("不允许入内")

运行结果:

1
不允许入内

7.2.4 (重要) in关键字

任务一:in检查是否包含某个值

知识点:a in b

a为变量,b为序列或集合类型的对象

Python提供了关键字in,用于遍历a是否在包含b中。返回的是TrueFalse

关键字in适用于任何的序列和集合类型的数据,比如strlisttuple

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 列表
nums = [2, 4, -14, 32, 1]
# res 为布尔值
res = (2 in nums)
print(res) # True

res = (3 in nums)
print(res) # False

# 字符串
name = 'LiLei'
res = ('L' in name)
print(res) # True

# range()对象
res = (1 in range(10))
print(res) # True

知识点:a not in b

使用not in来检查a是否不包含b

not关键字表示非

1
2
3
4
nums = [2, 4, -14, 32, 1]
# res 为布尔值
res = (0 not in nums)
print(res) # True

任务二:in用于if判断条件

知识点:if a in b:

a为变量,b为序列或集合类型的对象

in返回的是布尔值,因此可以用于if的判断条件

a存在于b之中时,a in b这个表达式的值为True,否则为假

1
2
3
4
5
6
7
8
#接收外部输入,判断是否在列表中
nums = [2, 4, -14, 32, 1]
val = int(input('输入整数:'))

if val in nums:
print('{}是列表元素!'.format(val))

# 输入是2,输出是2是列表元素!

知识点:

if a not in b,判断a是否不被b包含

1
2
3
4
5
6
7
8
#用户发言前,检查某用户是否在不黑名单中
banned_users = ['zhang san', 'li si', 'wang wu']
user = 'Lilei'

if user not in banned_users:
print(user.title() + "可以发言.")

# Lilei可以发言.

程序解析:if user not in banned_users:

如果user的值未包含在列表banned_users中,Python将返回True,并执行语句块

用户**’Lilei’未包含在列表banned_users中,因此输出消息:Lilei可以发言.**

任务三:in用于for循环遍历元素

知识点:for a in b:

其中a为临时变量,b为序列或集合类型的对象(可迭代对象)

in用于for循环,表示从b中逐个取元素,放到a临时变量中

b中的元素取完,循环结束

注意:Python中没有for a not in b

1
2
3
4
nums = [2, 4, -14, 32, 1]
for val in nums:
print(val, end=' ')
# 2 4 -14 32 1

习题:

题目要求:

5-2 更多的条件测试: 编写布尔表达式(if判断条件),然后对其结果进行TrueFalse的测试。

检查两个字符串相等和不等

使用函数**lower()**的测试

检查两个数字相等、不等、大于、小于、大于等于和小于等于

使用关键字andor的测试

测试特定的值是否包含在列表中

测试特定的值是否未包含在列表中

代码如下:

1
2
3
4
5
6
7
8
9
a=1
print("Is a=1? Ture")
print(a==1)
b="A"
print(b.lower()=="a")

print(b.lower()=="a" and a==1)

print(b.lower()=="a" or a==2)

运行结果:

1
2
3
4
5
Is a=1? Ture
True
True
True
True

7.3 进阶if语句

7.3.1 实例:二次方程求解

任务一:二次方程求解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 为了求开方,需要导入math数学模块
import math

# 一元二次方程求解函数
def solver(a, b, c):
print("求解一元二次方程的根(实数)\n")
# 对着公式理解程序
discRoot = math.sqrt(b * b - 4 * a * c)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print("根为:", root1, root2)


a = float(input("输入 a: "))
b = float(input("输入 b: "))
c = float(input("输入 c: "))

solver(a, b, c)

程序解析:

输入a=1,b=2,c=-3,此时二次方程有实根,程序输出的解

输入a=1,b=2,c=3,此时二次方程无实根,程序奔溃,触发ValueError: math domain error

程序奔溃的原因是当b²-4ac<0时,程序试图对负数进行开方,所以math模块报告错误

任务二:使用if-else语句解决程序奔溃问题

为解决上述问题,需要使用if语句来对b²-4ac是否大于0进行判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 一元二次方程求解函数
def solver(a, b, c):
print("求解一元二次方程的根(实数)\n")
discrim = b * b - 4 * a * c
if discrim < 0:
print("无实根")
else:
discRoot = math.sqrt(discrim)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print("根为:", root1, root2)


a = float(input("输入 a: "))
b = float(input("输入 b: "))
c = float(input("输入 c: "))

solver(a, b, c)

程序解析:

这个版本首先计算判别式的值,再if语句检查并确保它不是负数

如果discrim为负数,该程序永远不会尝试调用**math.sqrt()**进而避免了程序奔溃

该版本的二次方程求解程序解决了因为平方根为负导致程序奔溃问题,然而输入a=1,b=2,c=1时,程序输出为根为: -1.0 -1.0。相同的根,重复输出

任务三:嵌套if-else语句实现多路分支

为解决上述相同的根,重复输出问题,可以使用嵌套if-else语句来实现多路分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 一元二次方程求解函数
def solver(a, b, c):
print("求解一元二次方程的根(实数)\n")
discrim = b * b - 4 * a * c
if discrim < 0:
print("无实根")
else:
if discrim == 0:
root= -b / (2 * a)
print("单个根为:", root)
else:
discRoot = math.sqrt(discrim)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print("两个根为:", root1, root2)


a = float(input("输入 a: "))
b = float(input("输入 b: "))
c = float(input("输入 c: "))

solver(a, b, c)

程序解析:

使用了两个嵌套的if-else语句,根据discrim实现了3路分支,巧妙的满足了二次方程的无根、重根、和两个根的需求

然而,如果程序需要5路分支,那要嵌套多少个if-else语句?结果肯定是非常繁琐。在下节,将介绍Python的if-elif-else语句来解决此问题

7.3.2 if-elif-else语句

任务一:掌握if-elif-else语句

需求分析:

在开发中,使用 if 可以处理判断条件成立的情况

使用 else 可以处理条件不成立的情况

如果希望程序处理更复杂的情况,需要增加一些额外的条件,而不同的条件会执行不同的代码块,Python提供了 elif语句

为解决多路分支的判断,Python提供了if-elif-else语句,语法如下:

1
2
3
4
5
6
7
8
9
if <condition1>:
  <case1 statement>
elif <condition2>:
  <case2 statement>
elif <condition3>:
  <case3 statement>
...
else:
  <default statement>

知识点:if-elif-else语句实现n路分支

ifelif分支:按顺序依次检查,执行首次满足条件的,执行完后直接结束整个if-elif-else语句,后续语句不会被执行

else分支:如果没有一个True,则执行else的else分支是可选的。如果省略else分支,那么当不满足任何条件时,程序会跳出if语句

知识点:

if-elif-else语句只执行首次条件为True,剩余的条件语句块都不被执行。即使下面某个分支条件也为True,它的语句块也不会被执行

elifelse 都必须和 if 联合使用,而不能单独使用

可以将 ifelifelse 以及各自缩进的代码,看成一个 完整的代码块

任务二:对比逻辑运算符

知识点:

逻辑运算符,对多个条件按特定逻辑进行复合为更复杂的条件

相对于if-elif-else语句,逻辑运算符的复合条件会共享同一个代码块

1
2
3
if 条件1 and 条件2:
条件1满足 并且 条件2满足 执行的代码
……

任务三:输入数字实现多路判断

1
2
3
4
5
6
7
8
9
a = int(input('输入数字:'))
if a > 5:
print('a > 5: ', a)
elif a > 3:
print('a > 3: ', a)
else:
print('else:', a)

print('if语句之外')

程序解析:if-elif-else控制结构

当输入a=10,程序首先检查if a > 5,满足条件,则执行该条件下的语句,输出a > 5: 10,并跳出剩余的语句块。虽然elif a > 3也满足,程序不执行该条件下的语句

当输入a=4,程序首先检查if a > 5,不满足条件;依次再检查elif a > 3,满足条件,则执行该条件下的语句,输出a > 3: 4,并跳出剩余的语句块

当输入a=1,程序首先检查if a > 5,不满足条件;依次再检查elif a > 3,不满足条件;此时所有条件都不满足,则程序执行else的语句块

对于a=10,同时满足两个条件,虽然程序只执行了第一个条件,但是该程序设计的逻辑上出现了歧义,因此在实际程序设计中,避免条件有交集情况

知识点:

建议每个都是互斥的,即它们的交集为空

如果条件不互斥,容易出现逻辑上的歧义

7.3.3 elif演练

任务一:女友的节日

需求分析:

如果是 情人节 应该 买玫瑰/看电影

如果是 平安夜 应该 买苹果/吃大餐

如果是 生日 应该 买蛋糕

其他的日子每天都是节日啊……

定义 holiday_name 字符串变量记录节日名称

1
2
3
4
5
6
7
8
9
10
11
12
holiday_name = "平安夜"

if holiday_name == "情人节":
print("买玫瑰")
print("看电影")
elif holiday_name == "平安夜":
print("买苹果")
print("吃大餐")
elif holiday_name == "生日":
print("买蛋糕")
else:
print("每天都是节日啊……")

任务二:游乐场门票

在现实世界中,很多情况下需要考虑的情形都超过两个。例如,来看一个根据年龄段收费的游乐场:

4岁以下免费

4~18岁收费5元

18~65岁收费10元

65岁(含)收费5元

下面的代码确定一个人所属的年龄段,并打印一条包含门票价格的消息:

1
2
3
4
5
6
7
8
9
10
11
12
# 门票票价
age = int(input("输入年龄:"))
if 0 <= age < 4:
price = 0
elif 4 <= age < 18:
price = 5
elif 18 <= age < 65:
price = 10
else:
price = 5

print("票价为:{} 元!".format(price))

知识点:

Python并不要求if-elif结构后面必须有else代码块

else是一条包罗万象的语句,只要不满足if-elif条件的任意情况,就会执行else分支的代码,这容易导致有些程序逻辑流程变的不可控。所以在使用else分支时,一定要仔细检查该分支的各种情况

建议初学者if-elif-else语句,检查执行每个分支所需要满足的条件

1
2
3
4
5
6
7
8
9
10
11
12
# 门票票价
age = int(input("输入年龄:"))
if 0 <= age < 4:
price = 0
elif 4 <= age < 18:
price = 5
elif 18 <= age < 65:
price = 10
elif 65 <= age: #将else改为elif逻辑更清晰
price = 5

print("票价为:{} 元!".format(price))

任务三:二次方程的求解

之前使用了两个嵌套的if-else语句,实现了3路分支,巧妙的满足了二次方程的无根、重根、和两个根的需求。在本节,将使用if-elif-else语句来实现3路分支。相对于嵌套if-else语句,if-elif-else语句逻辑结构简明和清晰,不易出错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 一元二次方程求解函数
def solver(a, b, c):
print("求解一元二次方程的根(实数)\n")
discrim = b * b - 4 * a * c
# 3路分支,相对嵌套if-else逻辑更清晰
if discrim < 0:
print("无实根")
elif discrim == 0:
root = -b / (2 * a)
print("单个根为:", root)
else:
discRoot = math.sqrt(discrim)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print("两个根为:", root1, root2)


a = float(input("输入 a: "))
b = float(input("输入 b: "))
c = float(input("输入 c: "))

solver(a, b, c)

7.3.4 深入if嵌套

任务一:elif和if嵌套的应用场景

知识点:

elif语句:并联结构。同时判断多个条件,所有的条件是平级

if嵌套语句:串联结构。在上个条件满足的前提下,再增加额外if判断

知识点:

在开发中,使用 if 进行条件判断,如果希望在条件成立的执行语句中再增加条件判断,就可以使用if嵌套语句

if嵌套的语法格式,除了在前一级的if代码块中缩进之外和if语句没有区别

if嵌套的语法格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if 条件 1:
条件 1 满足执行的代码
……

if 条件 1 基础上的条件 2:
条件 2 满足时,执行的代码
……

# 条件 2 不满足的处理
else:
条件 2 不满足时,执行的代码

# 条件 1 不满足的处理
else:
条件1 不满足时,执行的代码
……

任务二:火车站安检

需求分析:**(仔细看需求后,再思考程序结构)**

1、定义布尔型变量 has_ticket 表示是否有车票

2、定义整型变量 knife_length 表示刀的长度,单位:厘米

3、首先检查是否有车票,如果有,才允许进行 安检

4、安检时,需要检查刀的长度,判断是否超过 20 厘米

  如果超过 20 厘米,提示刀的长度,不允许上车

  如果不超过 20 厘米,安检通过

5、如果没有车票,不允许进门

注意:if嵌套语句块的层级缩进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 定义布尔型变量 has_ticket 表示是否有车票
has_ticket = True

# 定义整数型变量 knife_length 表示刀的长度,单位:厘米
knife_length = 20

# 首先检查是否有车票,如果有,才允许进行 安检
if has_ticket:
print("有车票,可以开始安检...")
# 安检时,需要检查刀的长度,判断是否超过 20 厘米
# 如果超过 20 厘米,提示刀的长度,不允许上车
if knife_length >= 20:
print("不允许携带 %d 厘米长的刀上车" % knife_length)
# 如果不超过 20 厘米,安检通过
else:
print("安检通过,祝您旅途愉快……")

# 如果没有车票,不允许进门
else:
print("大哥,您要先买票啊")

7.3.5 一个还是多个if语句?

任务一:何时使用一个或多个if语句

知识点:

这里,将整个if-elif-else控制结构称为一个if语句

如果多个条件只需要满足一个,请使用一个if语句

if-elif-else结构功能强大,一系列的条件只需要一个满足的场景

即当满足任意一个条件后,Python就跳过剩余的条件

多个条件相互独立,需要每个都被测试,请使用多个独立的if语句

如果每个条件都需要被检查是否满足,那么一个if-elif-else语句就不能满足这个需求了

这时就需要用使用多个if语句,来分别检查每个条件是否满足

任务二:多个if语句检测多个条件

下面再来看前面比萨店示例。如果顾客点了两种配料,就需要确保在比萨中包含这些配料:

1
2
3
4
5
6
7
8
9
10
11
12
requested_toppings = ['mushrooms', 'cheese']

if 'mushrooms' not 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!")

程序解析:

  • 首先创建了一个列表requested_toppings,其中包含顾客点的配料
  • if 'mushrooms' not in requested_toppings:语句检查是否点了配料蘑菇'mushrooms',如果点了,就打印一条确认消息
  • if 'pepperoni' in requested_toppings:语句检查配料是否加了辣香肠'pepperoni',这里使用一个简单的if语句,而不是elifelse语句;因此不管前一个测试是否通过,都将进行执行这个判断条件
  • if 'extra cheese' in requested_toppings:语句检查是否要求多加芝士'extra cheese';这里也不管前面两个if语句的结果,都会执行这个if语句代码
  • 在这个例子中,程序会独立地检查每个判断条件

任务三:一个if语句不能检测多个条件

如果像下面这样转而使用if-elif-else结构,代码将不能正确地运行,因为有一个测试通过后,就会跳过余下的测试:

1
2
3
4
5
6
7
8
9
10
requested_toppings = ['mushrooms', 'extra cheese']

if 'mushrooms' in requested_toppings:
print("Adding mushrooms.")
elif 'pepperoni' in requested_toppings:
print("Adding pepperoni.")
elif 'extra cheese' in requested_toppings:
print("Adding extra cheese.")

print("\nFinished making your pizza!")

程序解析:

第一个条件**if ‘mushrooms’ in requested_toppings:,检查列表中是否包含‘mushrooms’**,它通过了,因此将在比萨中添加蘑菇

此时,Python会跳过if-elif-else结构的剩余条件,不再检查列表中是否包含**’extra cheese’‘pepperoni’**

其结果是,只添加了顾客点的第一种配料,但不会添加其他的配料

总之,如果你只想执行一个代码块,就使用if-elif-else结构;如果要运行多个代码块,就使用一系列独立的if语句

习题:

题目要求:

5-3 外星人颜色#1:假设在游戏中刚射杀了一个外星人,请创建一个名为alien_color的变量,并将其设置为**’green’‘yellow’‘red’**

编写一条if语句,检查外星人是否是绿色的;如果是,就打印一条消息,指出玩家获得了5个点

编写这个程序的两个版本,在一个版本中上述测试通过了,而在另一个版本中未通过(未通过测试时没有输出)

代码如下:

1
2
3
alien_color = ['green']
if 'green'in alien_color:
print("The player get 5 points")
1
2
3
alien_color = [ 'yellow', ]
if 'green' in alien_color:
print("The player get 5 points")

运行结果:

1
The player get 5 points
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
```

题目要求:

**5-4 外星人颜色#2**:像练习5-3那样设置外星人的颜色,并编写一个**if-else**结构

如果外星人是绿色的,就打印一条消息,指出玩家因射杀该外星人获得了5个点

如果外星人不是绿色的,就打印一条消息,指出玩家获得了10个点

编写这个程序的两个版本,在一个版本中执行**if**代码块,而在另一个版本中执行**else**代码块。

代码如下:

```python
alien_color = ['green']
if 'green' in alien_color:
print("The player get 5 points")
else:
print("The player get 10 points")
1
2
3
4
5
alien_color = ['green']
if 'red' in alien_color:
print("The player get 5 points")
else:
print("The player get 10 points")

运行结果:

1
The player get 5 points
1
The player get 10 points

题目要求:

5-5 外星人颜色#3:将练习5-4中的if-else结构改为if-elif-else结构

如果外星人是绿色的,就打印一条消息,指出玩家获得了5个点

如果外星人是黄色的,就打印一条消息,指出玩家获得了10个点

如果外星人是红色的,就打印一条消息,指出玩家获得了15个点

编写这个程序的三个版本,它们分别在外星人为绿色、黄色和红色时打印一条消息

代码如下:

1
2
3
4
5
6
7
alien_color = ['green']
if 'green' in alien_color:
print("The player get 5 points")
elif 'yellow' in alien_color:
print("The player get 10 points")
else:
print("The player get 15 points")

运行结果:

1
The player get 5 points

题目要求:

5-6 人生的不同阶段:设置变量age的值,再编写一个if-elif-else结构,根据age的值判断处于人生的哪个阶段

如果一个人的年龄小于2岁,就打印一条消息,指出他是婴儿

如果一个人的年龄为2(含)~4岁,就打印一条消息,指出他正蹒跚学步

如果一个人的年龄为4(含)~13岁,就打印一条消息,指出他是儿童

如果一个人的年龄为13(含)~20岁,就打印一条消息,指出他是青少年

如果一个人的年龄为20(含)~65岁,就打印一条消息,指出他是成年人

如果一个人的年龄超过65(含)岁,就打印一条消息,指出他是老年人

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
age = 18
if age < 2 :
string = 'baby'
if 2< age < 4 :
string = 'toddler'
if 4 <= age < 13 :
string = 'children'
if 13 <= age <20 :
string = 'teenager'
if 20 <= age < 65 :
string = 'adult'
if 65<= age :
string = 'older'

print("He is a " + str(string) +".")

运行结果:

1
He is a teenager.

题目要求:

5-7 喜欢的水果:创建一个列表,其中包含你喜欢的水果,再编写一系列独立的if语句,检查列表中是否包含特定的水果

将该列表命名为favorite_fruits,并在其中包含三种水果

编写5条if语句,每条都检查某种水果是否包含在列表中,如果包含在列表中,就打印一条消息,如“You really like bananas!”

代码如下:

1
2
3
4
5
6
7
8
9
10
11
favorite_fruits = ['banbana', 'apple', 'orange', 'grape', 'tomato']
if 'banana' in favorite_fruits:
print("You really like bananas!")
if 'apple' in favorite_fruits:
print("You really like apple!")
if 'watermelon' in favorite_fruits:
print("You really like watermelon!")
if 'grape' in favorite_fruits:
print("You really like grape!")
if 'pineapple'in favorite_fruits:
print("You really like pineapple!")

运行结果:

1
2
You really like apple!
You really like grape!

7.4 综合实例:石头剪刀布

学习目标:

强化 多个条件逻辑运算

体会 import 导入模块(“工具包”)的使用

需求分析:

1、从控制台输入要出的拳:石头(1)/剪刀(2)/布(3)

2、电脑随机出拳 :先假定电脑只会出石头,完成整体代码功能。

3、比较胜负

序号 规则
1 石头 胜 剪刀
2 剪刀 胜 布
3 布 胜 石头

任务一:基础代码实现

假定电脑就只会出石头,完成整体代码功能。注意,可以使用**.format()f-string方式来代替字符串的%**格式化输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 从控制台输入要出的拳 —— 石头(1)/剪刀(2)/布(3)
player = int(input("请出拳 石头(1)/剪刀(2)/布(3):"))

# 电脑 随机 出拳 - 假定电脑永远出石头
computer = 1

# format方式
print('玩家:{},电脑:{}'.format(player,computer))
# f-string方式
print(f'玩家:{player},电脑:{computer}')

# 比较胜负
# 如果条件判断的内容太长,可以在最外侧的条件增加一对大括号
# 再在每一个条件之间,使用回车,PyCharm 可以自动增加 8 个空格
if ((player == 1 and computer == 2) or
(player == 2 and computer == 3) or
(player == 3 and computer == 1)):

print("噢耶!!!电脑弱爆了!!!")
elif player == computer:
print("心有灵犀,再来一盘!")
else:
print("不行,我要和你决战到天亮!")

任务二:随机出拳

Python 中,要使用随机数,首先需要导入随机数random模块

1
import random

导入模块后,可以直接在模块名称后面敲一个 . 然后按 Tab 键,会提示该模块中包含的所有函数。random.randint(a, b) ,返回 [a, b] 之间的整数,包含 ab。例如:

1
2
3
random.randint(12, 20)  # 生成的随机数n: 12 <= n <= 20  
random.randint(20, 20) # 结果永远是 20
random.randint(20, 10) # 该语句是错误的,下限必须小于上限

7.5 初识异常处理机制

7.5.1 if和try异常处理机制

任务一:通过if语句来解决程序异常

在二次方程求解程序的例子中,在调用sqrt函数前,使用了if判断结构,避免了负数平方根而引起的程序奔溃。通过设置判断条件,来避免特定的程序错误

1
2
3
4
5
6
# 这程序是之前程序的片段,不需要运行
discRt = otherSqrt(b*b -4*a*c)
if discRt < 0:
  print("No real roots.")
else:
  do something

知识点:

在开发过程中,如果程序发生了错误,开发者可以通过Traceback来追踪错误的发生地和错误的原因

然而,当程序发布给用户之后,如果程序运行发生了错误,程序将会崩溃,而用户是无法通过修改程序来恢复程序正常使用的

另如果为程序的每个环节都设置if判断语句,那么程序将会变的非常复杂

任务二:try异常处理机制

为了提高程序的稳定性和健壮性,Python提供了try异常处理机制,帮助解决此类设计问题。异常处理机制允许开发者通过编写一些代码,来捕获和处理程序运行时出现的错误

知识点:try是一个异常处理机制

1
2
3
4
5
6
7
try:
<body>
except <ErrorType1>:
<handler1>
...
except:
<default handle>

程序在执行中,当遇到try语句时,它尝试执行语句

如果语句发生错误,Python会查找与错误类型相匹配的except错误处理分支

如果找到与之匹配的except :分支,那么就执行错误处理代码块

如果try语句中的语句块没有发生错误,则不会执行任何except错误处理分支

Traceback中的错误类型。最常见的except类型是IndexError(索引错误)、ValueError(值错误)、KeyError(键错误)、TypeError类型不匹配等

注意:try-except语句与if-elsif-else语句结构类似

7.5.2 常见的ErrorType

任务一:TypeError

TypeError 通常是由类型不匹配引起的

1
2
3
4
5
6
# 会发生TypeError
a = 'hello'
b = a + 1

#当发生错误后,该错误之后的语句是不能被执行的
print('something')
1
2
3
4
5
6
7
8
9
# 如果用户输入数字则会触发异常错误
a = 1
try:
b = 'hello' + a
except TypeError:
print('TypeError: ', TypeError)

#当发生错误后,try之后的语句依然能被执行
print('something')

任务二:as关键字提取错误信息

知识点:

**except TypeError:**只能捕获到错误,但不知道具体的错误。

except TypeError as e:通过as关键字,可以将详细的错误信息提取到变量e

1
2
3
4
5
6
# 如果用户输入数字则会触发异常错误
a = 1
try:
b = 'hello' + a
except TypeError as e:
print('TypeError: ', repr(e))

任务三:ValueError

ValueError通常是数值的非法计算,比如对负数开方等

1
2
3
4
import math

a = -1
math.sqrt(a)
1
2
3
4
5
6
a = -1

try:
math.sqrt(a)
except ValueError as e:
print(repr(e))

任务四:ZeroDivisionError

ZeroDivisionError通常是除数为0时发生的错误

1
2
3
4
try:
a = 1/0
except ZeroDivisionError as e:
print(repr(e))

任务五:IndexError

IndexError通常是列表或序列类型的索引越界引起的错误

1
2
3
4
5
li = [1,2,3]
try:
a = li[4]
except IndexError as e:
print(repr(e))

7.5.3 使用异常机制的二次方程

任务一:二次方程的异常处理

由于二次方程需要调用math.sqrt(),负数的平方根会引起程序异常。之前的程序通过if语句,让程序避免了错误的发生。这里,将使用try机制来实现程序的异常处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 一元二次方程求解函数
def solver(a, b, c):
print("求解一元二次方程的根(实数)\n")
discrim = b * b - 4 * a * c
try:
if discrim == 0:
root = -b / (2 * a)
print("单个根为:", root)
else:
# try可以捕获discrim的异常到ValueError
discRoot = math.sqrt(discrim)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print("两个根为:", root1, root2)
except ValueError:
print("无实根")


a = float(input("输入 a: "))
b = float(input("输入 b: "))
c = float(input("输入 c: "))

solver(a, b, c)

7.6 习题

题目要求:

1、当每周超出40小时以上的工作时间支付150%的工资。编写程序输入工作小时数和小时工资,并计算一周的总工资

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Person():
def __init__(self, wages, hours):
self.wages = wages
self.hours = hours

def get_wages(self):
if self.hours > 40:
pay = ((40 * self.wages) + (1.5 * self.wages * (self.hours - 40)))
print("Gross pay for week is : $%s" % pay)
else:
pay = self.wages * self.hours
print("weeks total pay: $%.2f" % pay)


wages = float(input("Enter hourly wage: "))
hours = int(input("Enter numbers of hours worked: "))
p = Person(wages, hours)
p.get_wages()
#wages=5
#hours=5

运行结果:

1
weeks total pay: $25.00

题目要求:

2、某位CS教授给出了5分的小测验,评分等级为5-A,4-B,3-C,2-D,1-E,0-F。编写一个程序,接受测验得分作为输入,并使用判断结构来计算相应的等级

代码如下:

1
2
3
4
a=int(input())
ls1={5:'A',4:'B',3:'C',2:'D',1:'E',0:'F'}
print(ls1[a])
#5

运行结果:

1
A

题目要求:

3、某位CS教授给出了100分的考试,分级为90~100:A,80~89:B,70~79:C,60~69:D,<60:F。编写一个程序,将考试分数作为输入,并使用判断结构来计算相应的等级

代码如下:

1
2
3
4
5
6
7
8
9
10
11
def gradeconvert():
gradeLevel = "FDCBA"
grade = float(input("Enter the grade: ")) # 80
gradeLev = int(grade/10 - 5)
if gradeLev < 0:
print("The converted grade level is: F")
elif gradeLev == len(gradeLevel):
print("The converted grade level is: A")
else:
print("The converted grade level is: ", gradeLevel[gradeLev])
gradeconvert()

运行结果:

1
The converted grade level is:  B

题目要求:

4、某所大学根据学生拿到的学分对学生分年级。小于7学分的学生是大一新生。至少有7个学分才是大二,16分以上是大三,26分以上是大四。编写一个程序,根据获得的学分数计算年级

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
credit = eval(input("请输入学分:"))
if credit < 7 :
string = '大一新生'
if 7 <= credit < 16 :
string = '大二学生'
if 16 <= credit <26 :
string = '大三学生'
if credit >= 26 :
string = '大四学生'

print("这是一名" + str(string) +"。")

#5

运行结果:

1
2

这是一名大一新生。

题目要求:

5、身体质量指数(BMI)的计算公式是人的体重(以磅计)乘以720,再除以人的身高(以英寸计)的平方。BMI在19~25范围内(包括边界值)被认为是健康的。编写一个程序,计算人的BMI,并打印一条消息,告诉他们是在健康范围之上、之中还是之下

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
height = eval((input("请输入你的身高(m):")))
weight =eval((input("请输入你的体重(kg):")))
BMI = weight / pow(height,2)

if BMI < 19:
print("健康范围之下")
elif (BMI >= 19 and BMI <= 25):
print("健康范围之中")
elif BMI > 25:
print("健康范围之上")
#1.76
#65

运行结果:

1
健康范围之中

题目要求:

6、超速罚单政策:300元加上超速部分每mph(一英里每小时)40元,如果超过90mph再追加罚款500元。编写一个程序,接受速度限制和计时速度,并打印一条消息,表明速度合法,或者在速度非法时,打印罚款

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def ask_limit():
limit = float(input ("What was the speed limit? "))

return limit
def ask_speed():
speed = float(input ("What was your clocked speed? "))
return speed
def findfine(speed, limit):
if speed > 90:
bigfine = ((speed - limit) * 5 + 500)
print("your fine is", bigfine)
elif speed <= limit:
print("you were traveling a legal speed")
else:
fine = ((speed - limit) * 40 + 300)
print("your fine is", fine)

def main():
limit = ask_limit()
speed = ask_speed()
findfine(speed, limit)
main()
#100
#80

运行结果:

1
you were traveling a legal speed

题目要求:

7、计算1982~2048年的复活节的计算公式如下:令a = year%19, b = year%4, c = year%7, d = (19a + 24)%30, e = (2b +4c +6d + 5)%7。复活节的日期是3月22日+ d + e(可能在4月)。写一个程序,输入年份,验证它在适当的范围,然后打印出那一年复活节的日期

代码如下:

1
2
3
4
5
6
7
8
9
10
11
year=int(input())
a=year%19
b=year%4
c=year%7
d=(19a + 24)%30
e= (2b +4c +6d + 5)%7
sum=22+d+e
if sum<=31:
print(f'3月{sum}日')
else
print(f'4月{sum-31}日')

评论