第四章 程序的控制结构
程序的基本结构
程序由三种基本结构组成:
- 顺序结构
- 分支结构
- 循环结构
这些基本结构都有一个入口和一个出口。任何程序都由这三种基本结构组合而成
微实例
- 计算圆的面积和周长
- 计算绝对值
- 整数累加
#输入半径,计算圆的面积和周长
R = eval(input("请输入圆半径:"))
S = 3.1415*R*R
L = 2*3.1415*R
print("面积和周长:",S,L)
请输入圆半径:3
面积和周长: 28.2735 18.849
#输入一个实数,计算其绝对值
R = eval(input("输入实数:"))
if (R < 0):
R = -R
print("绝对值",R)
输入实数:-2.8
绝对值 2.8
#输入正整数,计算从1累加到该数的和
R = eval(input("请输入正整数:"))
i, S = 0, 0
while (i<=R):
S = S + i
i = i + 1
print("累加求和",S)
请输入正整数:100
累加求和 5050
程序的分支结构
单分支结构: if语句
Python中if语句的语法格式如下:
if <条件>:
语句块
- 语句块是if条件满足后执行的一个或多个语句序列
- 语句块中语句通过与if所在行形成缩进表达包含关系
- if语句首先评估<条件>的结果值,如果结果为True,则执行语句块里的语句序列,然后控制转向程序的下一条语句。如果结果为False,语句块里的语句会被跳过。
- if语句中语句块执行与否依赖于条件判断。但无论什么情况,控制都会转到if语句后与该语句同级别的下一条语句
- if语中<条件>部分可以使用任何能够产生True或False的语句
- 形成判断条件最常见的方式是采用关系操作符
微实例4.4:PM 2.5空气质量提醒(1)
输入:接收外部输入PM2.5值
处理:
if PM2.5值 >= 75,打印空气污染警告
if 35 <= PM2.5值 < 75,打印空气污染警告
if PM2.5值 < 35,打印空气质量优,建议户外运动
输出:打印空气质量提醒
PM = eval(input("请输入PM2.5数值: "))
if 0<= PM < 35:
print("空气优质,快去户外运动!")
if 35 <= PM <75:
print("空气良好,适度户外活动!")
if 75 <= PM:
print("空气污染,请小心!")
请输入PM2.5数值: 50
空气良好,适度户外活动!
二分支结构: if-else语句
Python中if-else语句用来形成二分支结构,语法格式如下:
if <条件>:
<语句块1>
else:
<语句块2>
- <语句块1>是在if条件满足后执行的一个或多个语句序列
- <语句块2>是if条件不满足后执行的语句序列
- 二分支语句用于区分<条件>的两种可能True或者False,分别形成执行路径
微实例4.5:PM 2.5空气质量提醒(2)
PM = eval(input("请输入PM2.5数值: "))
if PM >= 75:
print("空气存在污染,请小心!")
else:
print("空气没有污染,可以开展户外运动!")
请输入PM2.5数值: 50
空气没有污染,可以开展户外运动!
二分支结构还有一种更简洁的表达方式,适合通过判断返回特定值,语法格式如下:
<表达式1> if <条件> else <表达式2>
PM = eval(input("请输入PM2.5数值: "))
print("空气{}污染!".format("存在" if PM >= 75 else "没有"))
请输入PM2.5数值: 80
空气存在污染!
多分支结构: if-elif-else语句
Python的if-elif-else描述多分支结构,语句格式如下:
if <条件1>:
<语句块1>
elif <条件2>:
<语句块2>
...
else:
<语句块N>
- 多分支结构是二分支结构的扩展,这种形式通常用于设置同一个判断条件的多条执行路径。
- Python依次评估寻找第一个结果为True的条件,执行该条件下的语句块,同时结束后跳过整个if-elif-else结构,执行后面的语句。如果没有任何条件成立,else下面的语句块被执行。else子句是可选的。
微实例4.6:PM 2.5空气质量提醒(3)
PM = eval(input("请输入PM2.5数值: "))
if 0<= PM < 35:
print("空气优质,快去户外运动!")
elif 35 <= PM <75:
print("空气良好,适度户外活动!")
else:
print("空气污染,请小心!")
请输入PM2.5数值: 30
空气优质,快去户外运动!
实例:身体质量指数BMI
BMI的定义如下:
BMI = 体重(kg)÷身高2(m2)
例如,一个人身高1.75米、体重75公斤,他的BMI值为24.49
编写一个根据体重和身高计算BMI值的程序,并同时输出国际和国内的BMI指标建议值
height, weight = eval(input("请输入身高(米)和体重\
(公斤)[逗号隔开]: "))
bmi = weight / pow(height, 2)
print("BMI数值为:{:.2f}".format(bmi))
wto, dom = "", ""
if bmi < 18.5: # WTO标准
wto = "偏瘦"
elif bmi < 25: # 18.5 <= bmi < 25
wto = "正常"
elif bmi < 30: # 25 <= bmi < 30
wto = "偏胖"
else:
wto = "肥胖"
if bmi < 18.5: # 我国卫生部标准
dom = "偏瘦"
elif bmi < 24: # 18.5 <= bmi < 24
dom = "正常"
elif bmi < 28: # 24 <= bmi < 28
dom = "偏胖"
else:
dom = "肥胖"
print("BMI指标为:国际'{0}', 国内'{1}'".format(wto, dom))
请输入身高(米)和体重(公斤)[逗号隔开]: 1.75,74
BMI数值为:24.16
BMI指标为:国际'正常', 国内'偏胖'
height, weight = eval(input("请输入身高(米)和体重\
(公斤)[逗号隔开]: "))
bmi = weight / pow(height, 2)
print("BMI数值为:{:.2f}".format(bmi))
wto, dom = "", ""
if bmi < 18.5:
wto, dom = "偏瘦", "偏瘦"
elif 18.5 <= bmi < 24:
wto, dom = "正常", "正常"
elif 24 <= bmi < 25:
wto, dom = "正常", "偏胖"
elif 25 <= bmi < 28:
wto, dom = "偏胖", "偏胖"
elif 28 <= bmi < 30:
wto, dom = "偏胖", "肥胖"
else:
wto, dom = "肥胖", "肥胖"
print("BMI指标为:国际'{0}', 国内'{1}'".format(wto, dom))
请输入身高(米)和体重(公斤)[逗号隔开]: 1.75,73
BMI数值为:23.84
BMI指标为:国际'正常', 国内'正常'
程序的循环结构
遍历循环: for语句
遍历循环:
根据循环执行次数的确定性,循环可以分为确定次数循环和非确定次数循环。确定次数循环指循环体对循环次数有明确的定义循环次数采用遍历结构中元素个数来体现
Python通过保留字for实现“遍历循环” :
for <循环变量> in <遍历结构>:
<语句块>
遍历结构可以是字符串、文件、组合数据类型或range()函数:
遍历循环还有一种扩展模式,使用方法如下:
for <循环变量> in <遍历结构>:
<语句块1>
else:
<语句块2>
当for循环正常执行之后,程序会继续执行else语句中内容。else语句只在循环正常执行之后才执行并结束
for s in "BIT":
print("循环进行中:" + s)
else:
print("循环正常结束")
循环进行中:B
循环进行中:I
循环进行中:T
循环正常结束
无限循环: while语句
- 无限循环一直保持循环操作直到特定循环条件不被满足才结束,不需要提前知道确定循环次数。
- Python通过保留字while实现无限循环,使用方法如下:
while <条件>:
<语句块>语句块
- 无限循环也有一种使用保留字else的扩展模式:
while <条件>:
<语句块1>
else:
<语句块2>
s, idx = "BIT", 0
while idx < len(s):
print("循环进行中: " + s[idx])
idx += 1
else:
print("循环正常结束")
循环进行中: B
循环进行中: I
循环进行中: T
循环正常结束
循环保留字: break和continue
- 循环结构有两个辅助保留字:break和continue,它们用来辅助控制循环执行
- break用来跳出最内层for或while循环,脱离该循环后程序从循环后代码继续执行
- continue用来结束当前当次循环,即跳出循环体中下面尚未执行的语句,但不跳出当前循环。
- 对于while循环,继续求解循环条件。而对于for循环,程序流程接着遍历循环列表
for s in "BIT":
for i in range(10):
print(s, end="")
if s=="I":
break
BBBBBBBBBBITTTTTTTTTT
for s in "PYTHON":
if s=="T":
continue
print(s, end="")
PYHON
for s in "PYTHON":
if s=="T":
break
print(s, end="")
PY
continue语句和break语句的区别是:
- continue语句只结束本次循环,而不终止整个循环的执行。
- break语句则是结束整个循环过程,不再判断执行循环的条件是否成立
random库的使用
使用random库主要目的是生成随机数,因此,读者只需要查阅该库的随机数生成函数,找到符合使用场景的函数使用即可。这个库提供了不同类型的随机数函数,所有函数都是基于最基本的random.random()函数扩展而来。
对random库的引用方法与math库一样,采用下面两种方式实现:
import random
或
from random import *
#输出所有的变量结果
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
from random import *
random()
uniform(1,10)
uniform(1,20)
randrange(0,100,4) #从0开始到100以4递增的元素中随机返回
choice(range(100))
ls = list(range(10))
print(ls)
shuffle(ls)
print(ls)
0.3009407488048058
7.634623047949269
7.6703007509187024
76
39
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[8, 4, 2, 3, 7, 6, 5, 1, 0, 9]
生成随机数之前可以通过seed()函数指定随机数种子,随机种子一般是一个整数,只要种子相同,每次生成的随机数序列也相同。这种情况便于测试和同步数据
seed(125) # 随机种子赋值125
"{}.{}.{}".format(randint(1,10),randint(1,10),randint(1,10))
"{}.{}.{}".format(randint(1,10),randint(1,10),randint(1,10))
seed(125) # 再次给随机种子赋值125
"{}.{}.{}".format(randint(1,10),randint(1,10),randint(1,10))
'4.4.10'
'5.10.3'
'4.4.10'
实例:π的计算
- π(圆周率)是一个无理数,即无限不循环小数。精确求解圆周率π是几何学、物理学和很多工程学科的关键。
- 对π的精确求解曾经是数学历史上一直难以解决的问题之一,因为π无法用任何精确公式表示,在电子计算机出现以前,π只能通过一些近似公式的求解得到,直到1948年,人类才以人工计算方式得到π的808位精确小数。
- 随着计算机的出现,数学家找到了另类求解π的另类方法:蒙特卡罗(Monte Carlo)方法,又称随机抽样或统计试验方法。
应用蒙特卡罗方法求解π的基本步骤如下:
- 随机向单位正方形和圆结构,抛洒大量“飞镖”点
- 计算每个点到圆心的距离从而判断该点在圆内或者圆外
- 用圆内的点数除以总点数就是π/4值。
随机点数量越大,越充分覆盖整个图形,计算得到的π值越精确。实际上,这个方法的思想是利用离散点值表示图形的面积,通过面积比例来求解π值。
from random import random
from math import sqrt
from time import clock
DARTS = 1000000
hits = 0.0
clock()
for i in range(1, DARTS+1):
x, y = random(), random()
dist = sqrt(x ** 2 + y ** 2)
if dist <= 1.0:
hits = hits + 1
pi = 4 * (hits/DARTS)
print("Pi值是{}.".format(pi))
print("运行时间是: {:5.5}s".format(clock()))
68.80672016579628
Pi值是3.143716.
运行时间是: 71.452s
异常处理机制
异常处理: try-except语句
看一个小程序片段:
num = eval(input("请输入一个整数:"))
print(num ** 2)
请输入一个整数:abc
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-32-6fa4201aa066> in <module>()
----> 1 num = eval(input("请输入一个整数:"))
2 print(num ** 2)
<string> in <module>()
NameError: name 'abc' is not defined
当用户输入的不是整数,Python解释器返回了异常信息,同时程序退出
- Python异常信息中最重要的部分是异常类型,它表明了发生异常的原因,也是程序处理异常的依据。
- Python使用try-except语句实现异常处理,基本的语法格式如下:
try:
<语句块1>
except <异常类型>:
<语句块2>
try:
num = eval(input("请输入一个整数: "))
print(num**2)
except NameError:
print("输入错误,请输入一个整数!")
请输入一个整数: abc
输入错误,请输入一个整数!
异常的高级用法
try-except语句可以支持多个except语句,语法格式如下:
try:
<语句块1>
except <异常类型1>:
<语句块2>
….
except <异常类型N>:
<语句块N+1>
except:
<语句块N+2>
最后一个except语句没有指定任何类型,表示它对应的语句块可以处理所有其他异常。这个过程与if-elif-else语句类似,是分支结构的一种表达
try:
alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
idx = eval(input("请输入一个整数: "))
print(alp[idx])
except NameError:
print("输入错误,请输入一个整数!")
except:
print("其他错误")
请输入一个整数: 26
其他错误
该程序将用户输入的数字作为索引从字符串alp中返回一个字符,当用户输入非整数字符时,except NameError异常被捕获到,
提示升用户输入类型错误,当用户输入数字不在0到25之间时,异常被except捕获,程序打印其他错误信息
除了try和except保留字外,异常语句还可以与else和finally保留字配合使用,语法格式如下:
try:
<语句块1>
except <异常类型1>:
<语句块2>
else:
<语句块3>
finally:
<语句块4>
try:
alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
idx = eval(input("请输入一个整数: "))
print(alp[idx])
except NameError:
print("输入错误,请输入一个整数!")
else:
print("没有发生异常")
finally:
print("程序执行完毕,不知道是否发生了异常")
请输入一个整数: 5
F
没有发生异常
程序执行完毕,不知道是否发生了异常