4 程序的控制结构
4.1 程序的分支语句
4.1.1 单分支结构
如果条件为真,则执行下面的语句
结构:
if 条件:
语句块
例如:
if True:
print(“python”)
当条件是True时,后面的语句恒执行,相当于C语言的1
4.1.2 二分支结构
根据判断条件选择不同的路径
结构:
if 条件:
语句块1
else:
语句块2
紧凑结构:
适用于表达简单逻辑
表达式1 if 条件 else 表达式2
条件成立,执行表达式1;不成立,执行表达式2
例如:
>>> print("猜对了") if eval(input())==66 else print("猜错了")
23
猜错了
>>> print("猜对了") if eval(input())==66 else print("猜错了")
66
猜对了
4.1.3 多分支结构
结构:
if 条件1:
语句块1
elif 条件2:
语句块2
… …
else:
语句块n
要注意多条件之间的包含关系;注意变量取值范围的覆盖。
例如:
score=eval(input())
if score>=90:
grade="A"
elif score>=80:
grade="B"
elif score>=70:
grade="C"
elif score>=80:
grade="D"
else:
grade="E"
print("{}分属于{}等级".format(score,grade))
4.1.4 条件判断及组合
条件判断操作符
< <= >= > == !=
与数学符合相对应
条件组合保留字
and or not
4.1.5 程序的异常处理
示例:
num=eval(input("请输入整数:"))
print(num**2)
运行:
请输入整数:abc
Traceback (most recent call last):
File "E:/python/测试.py", line 2, in <module>
num=eval(input("请输入整数:"))
File "<string>", line 1, in <module>
NameError: name 'abc' is not defined
异常类型
异常处理的基本使用
try:
语句块1
except 异常类型(可不填):
语句块2
执行过程是:如果语句块1发生异常,则执行语句块2
例如:
try:
num=eval(input("请输入整数:"))
print(num**2)
except: #except NameError:
print("输入的不是整数")
结果:
请输入整数:abd
输入的不是整数
异常处理的高级处理用法
try:
语句块1
except:
语句块2
else:
语句块3
finally:
语句块4
说明:
finally对应的语句块4一定执行
else对应的语句块3在不发生异常时执行
执行过程是:先执行语句块1的代码,如果不发生异常,去执行语句块3;如果发生异常,执行语句块2;最后都要执行语句块4
4.2 实例五:BMI
4.2.1 问题分析
BMI=体重(kg)/身高²(m²)
国内 国际
偏瘦 <18.5 <18.5
正常 18.5-24 18.5-25
偏胖 24-28 25-30
肥胖 ≥28 ≥30
输入:身高和体重两个值
输出:国内标准和国外标准
4.2.2 实例编写
分别写
国际标准
height, weight = eval(input("请输入身高(米)和体重(公斤)[逗号隔开]: ")) bmi = weight / pow(height, 2)
print("BMI 数值为:{:.2f}".format(bmi))
who = ""
if bmi < 18.5:
who = "偏瘦"
elif 18.5 <= bmi < 25:
who = "正常"
elif 25 <= bmi < 30:
who = "偏胖"
else:
who = "肥胖"
print("BMI 指标为:国际'{0}'".format(who))
国内标准
height, weight = eval(input("请输入身高(米)和体重\(公斤)[逗号隔开]: "))
bmi = weight / pow(height, 2)
print("BMI 数值为:{:.2f}".format(bmi))
nat = ""
if bmi < 18.5:
nat = "偏瘦"
elif 18.5 <= bmi < 24:
nat = "正常"
elif 24 <= bmi < 28:
nat = "偏胖"
else:
nat = "肥胖"
print("BMI 指标为:国内'{0}'".format(nat))
整合一体
分析共同区间
height, weight = eval(input("请输入身高(米)和体重(公斤)[逗号隔开]: "))
bmi = weight / pow(height, 2)
print("BMI 数值为:{:.2f}".format(bmi))
who, nat = "", ""
if bmi < 18.5:
who, nat = "偏瘦", "偏瘦"
elif 18.5 <= bmi < 24:
who, nat = "正常", "正常"
elif 24 <= bmi < 25:
who, nat = "正常", "偏胖"
elif 25 <= bmi < 28:
who, nat = "偏胖", "偏胖"
elif 28 <= bmi < 30:
who, nat = "偏胖", "肥胖"
else:
who, nat = "肥胖", "肥胖"
print("BMI 指标为:国际'{0}', 国内'{1}'".format(who, nat))
4.3 程序的循环结构
4.3.1 遍历循环
结构:
for 循环变量 in 遍历结构:
(语句块)
由保留字for和in组成,完整遍历所有元素后结束
每次循环,从遍历结构中获取元素,放入循环变量i,然后执行语句块
遍历循环的应用:
计数循环
range(N):产生0到N-1的整数序列,共N个
range(M,N):产生M到N-1的整数序列,共N-M个
range(M,N,K):产生M到N-1且步长为K的整数序列
for 循环变量 in range(N):
语句块
遍历由range函数产生的数字序列,产生循环,其中i在语句块中可以不用
字符串遍历循环
for 循环变量 in 字符串:
语句块
每次循环,从“字符串”中获取元素,放入循环变量c,然后执行语句块
例如:
for c in "python":
print(c,end="/")
输出结果:
p/y/t/h/o/n/
列表遍历循环
for 循环变量 in 列表:
语句块
每次循环,从“列表”中获取元素,放入循环变量,然后执行语句块
例如:
for item in [123,abc,aoe]:
print(item,end="/")
输出结果:
123/abc/aoe
文件遍历循环
for 循环变量 in 文件标识符:
语句块
遍历文件里的每一行line
文件标识符:对一个外部文件,通过Python函数打开,如果以字符形式打开,则表示为一个文件标识名字,相当于用一个变量名来标识系统里的一个文件。
还能对元组、字典类型进行循环
也就是说,只要有多个元素就可以依次循环
4.3.2 无限循环
由条件控制的循环运行方式,如果条件成立,则执行语句块,执行后再次判断条件,直到条件不满足则结束循环
结构:
while 条件:
语句块
例如:
a=9
while a>5:
a=a-1
print(a,end=" ")
结果:
如果a=a-1改为a=a+1,这会陷入无限循环,那么如何停止循环?
Ctrl+C 退出执行
4.3.3 循环控制保留字
break:跳出并结束当前循环,进入循环之后的语句
continue:结束当次循环,进入下一次循环
例如:
for c in "python":
if c=="y":
continue
print(c,end="/")
#--------------------------------------
for c in "python":
if c=="y":
break
print(\n c,end="!")
输出结果:
p/t/h/o/n/
p!
4.3.4 循环的高级用法
与else搭配
for 循环变量 in 遍历结构: # 或者while 条件:
语句块1
else:
语句块2
当循环没有被break语句退出,而是循环自己结束了正常退出,那就“奖励”它去执行else的语句块(与异常处理相似);判断是否被break退出,进而能设计程序,使之便捷
4.4 模块3:random库的使用
4.4.1 基本介绍
random库是使用随机数的Python标准库
计算机产生的随机数为伪随机数
伪随机数:采用梅森旋转算法生成的伪随机序列中的元素
使用方法:import random
基本随机数函数:seed() random()
扩展随机数函数:randint() getrandbits() uniform() randrange() choice() shuffle()
4.4.2 基本随机数函数
随机数种子
相当于基数,根据种子通过梅森算法生成序列
种子相同,生成的随机数相同
seed()
用法:random.seed(随机种子)
可以不调用seed函数,默认当前系统时间为种子(第一次使用时的时间)
可以只给一次种子
为什么给种子?种子相同,每次运行时生成的随机数也相同,有益于程序复现或程序运行的过程;如果不给种子,系统时间时刻在变,每次运行的随机数完全随机,不可再现。以此是否要seed看需求
random()
生成一个[0.0 , 1.0) 之间的随机小数
用法:random.random()
>>> random.seed(10)
>>> random.random()
0.5714025946899135
>>> random.random()
0.4288890546751146
>>> random.random()
0.5780913011344704
>>> random.seed(10)
>>> random.random()
0.5714025946899135
>>> random.random()
0.4288890546751146
>>> random.random()
0.5780913011344704
>>> import random
>>> random.random()
0.20609823213950174
>>> random.random()
0.81332125135732
4.4.3 扩展随机数函数
randint()
用法:random.randint(a,b) 生成整数[a,b]之间的数
>>> random.randint(3,13)
13
>>> random.randint(3,13)
5
randrange()
用法:random.randrange(m,n[,k])生成一个[m,n)之间,以k为步长的随机整数
>>> random.randrange(3,13,3)
3
>>> random.randrange(3,13,3)
12
>>> random.randrange(3,13,3)
6
>>> random.randrange(3,13,3)
9
>>> random.randrange(3,13,3)
12
getrandbits()
用法:random.getrandbits(k) 生成一个k比特长的随机整数
>>> random.getrandbits(1)
0
>>> random.getrandbits(3)
0
>>> random.getrandbits(3)
4
>>> random.getrandbits(6)
0
>>> random.getrandbits(6)
15
>>> random.getrandbits(16)
8780
>>> random.getrandbits(20)
204423
比特长:相当于一个数转换二进制后的位数
例如:
0-1 0-1
0-11 0-3
0-111 0-7
... ...
0-1111111111111111 0-65535
uniform()
用法:random.uniform(a,b) 生成一个[a,b]之间的随机小数(最长小数点后16位)
>>> random.uniform(2,6)
3.6850559795981113
>>> random.uniform(2,6)
5.30739291533723
>>> random.uniform(2,6)
3.049284441972707
以下两个函数与序列无关
choice()
用法:random.choice(待选元素) 从待选元素中选一个
>>> random.choice([5,6,6,8,1,19])
6
>>> random.choice(['g','j','h'])
'h'
shuffle()
用法:random.shuffle(待排元素) 随机打乱序列
>>> random.shuffle([5,6,8,1,19])
>>> s=[5,6,8,1,19]
>>> random.shuffle(s)
>>> print(s)
[6, 1, 8, 5, 19]
4.5 实例六:圆周率的计算
4.5.1 问题分析
近似计算公式:
蒙特卡罗方法计算圆周率:正方形内切圆的面积与正方形面积的比值与圆周率有关,圆的面积用类似数格子的方法估算
4.5.2 实例编写
近似公式法
pi=0
n=100 #循环的次数
for k in range(n):
pi=pi+1/pow(16,k)*(4/(8*k+1)-2/(8*k+4)-1/(8*k+5)-1/(8*k+6))
print("圆周率π={}".format(pi))
结果:
圆周率π=3.141592653589793
知识补充:单行代码过长?
在行末加上“\”再换行
例如:pi=pi+1/pow(16,k)(4/(8k+1)-2/(8k+4)-1/(8k+5)-1/(8*k+6))
可以改写为:
pi=pi+1/pow(16,k)*(\
4/(8*k+1)-2/(8*k+4)-\
1/(8*k+5)-1/(8*k+6))
蒙特卡罗方法
import random
import time
# from random import random
# from time import perf_counter #这样引入不用加库名.
#area=eval(input("请输入正方形大小"))
area=1000*1000 #正方形的点数(循环随机的次数)
hit=0.0 #落在圆内的点数
start=time.perf_counter()
for i in range(1,area+1): #1-100w
x,y=random.random(),random.random()
d=pow(x**2+y**2,0.5) #随机的点到原点(圆心)的距离
if d<=1.0:
hit=hit+1
pi=4*(hit/area) #上面用的是1/4的圆和正方形
print("圆周率π={}".format(pi))
print("运行时间为:{:.5f}s".format(time.perf_counter()-start))
输出结果:
圆周率π=3.142516 运行时间为:0.79008s
#每次得到的圆周率值不一样,因为是随机的
圆周率π=3.143888 运行时间为:0.75694s