Python与医药数据处理 第四章
第四章 程序的控制结构
前言
我们阅读本章目录对知识进行回顾,主要介绍了四种结构:顺序结构,分支结构,循环结构,异常处理结构。不少结构都有相应的关键字作为引导,并且通过缩进来严格控制结构从属关系
顺序结构:即按照代码语句的逻辑先后顺序执行,语句之间为先后顺序关系。顺序结构是任何程序的基本结构,也被包含在其他结构中。
分支结构:即出现了根据不同情况进行选择,出现可以选择的分支(“岔路”)的情况,语句之间为判断和选择关系。分为if引导的单分支结构,if...else...引导的二分支结构,if...elif...else...引导的多分支结构,分支嵌套
循环结构:即规定的一段代码按要求重复执行,重复执行的内容称为循环体。循环结构可以有while引导的条件循环和for引导的遍历循环两种,并且都可以使用else扩展
异常处理结构:由try...except...引导,主要解决如果try代码块发生异常后做什么,正常运行后做什么,逻辑上也是类似于分支结构的一种判断与选择的结构
4.1 分支结构
4.1.1 单分支结构(if)
if <条件表达式>:
<语句块>
这个结构中,通过 <条件表达式> 来判断是否执行 <语句块>,如果表达式值为 \(True\) 则执行 <语句块>;为 \(False\) 则不执行
<条件表达式> 的返回值必须为 \(True\) 或 \(False\),否则会引发错误,我们在 3.3.3 中列出过返回值为逻辑类型的运算
4.1.2 二分支结构(if...else...)
if <条件表达式>:
<语句块 1>
else:
<语句块 2>
这个结构中,通过 <条件表达式> 来判断执行哪一段 <语句块>,如果表达式值为 \(True\) 则执行 <语句块1>,为 \(False\) 则进入else结构执行 <语句块2>
这个结构还有一种紧凑形式,只在两个语句块都仅含一行代码时使用:
<表达式1> if <条件表达式> else <表达式2>
4.1.3 多分支结构(if...elif...else...)
if <条件表达式 1>:
<语句块 1>
elif <条件表达式 2>:
<语句块 2>
...
else:
<语句块 n>
从if开始依次执行每一个条件表达式的判断,如果在某一个判断中为 \(True\) 则执行该条件表达式对应的语句块,完成后直接退出整个多分支结构,不再执行后续的所有判断语句
如果依次进行所有的 if 和 elif 判断结果都为 \(False\),那么最后进入else结构直接执行相应语句块
4.1.4 分支嵌套
if <条件表达式 1>:
<语句块 1>
if <条件表达式 1.1>:
<语句块 1.1>
else:
<语句块 1.2>
else <条件表达式 2>:
<语句块 2>
if <条件表达式 2.1>:
<语句块 2.1>
else:
<语句块 2.2>
我们有时候会有进行完一次判断之后再进行一次判断的需求,比如评估一个苹果好不好,会先看表面有没有坏,再看外观红不红,再吃口味甜不甜等等,最后才得出结论,这就是分支嵌套的过程。顾名思义,分支嵌套就是综合了上述三种基础分支结构,层层叠加的结果,以达到解决复杂的分支结构问题的目的。
理解了分支结构的逻辑,分支嵌套本身并没有什么值得再讲的了,但值得注意的是,嵌套级数的从属关系仍然由缩进严格控制
4.2 循环结构
4.2.1 遍历循环结构(for)
for <循环变量> in <可迭代对象>:
<循环体>
创建 for 结构下的局部变量 <循环变量>。每一次循环前,基于 <可迭代对象> 对 <循环变量> 进行赋值,然后执行 <循环体> 代码块。如此往复,直到所有可迭代对象都完成过循环结束
常见的可迭代对象有:字符串、列表、元组、字典、集合、文件、range()、迭代器
4.2.2 条件循环结构(while)
while <条件表达式>:
<循环体>
在进行每一次循环前,进行 <条件表达式> 的判断,如果其值为真,则执行 <循环体>,如果为假,则结束循环
特殊地 while 1 while True的表达式恒为真,故表示无限循环,退出无限循环需要用 Ctrl+C 来完成
4.2.3 break 与 continue 语句
- \(break\) 语句:"break" 意为打破循环,执行该语句直接结束本次循环体的执行,并跳出该层循环结构。需要注意的是,出现循环嵌套时,只能跳出该语句所在的最内层循环体,如:
for i in ...: # 将该层循环称为 <循环1>
...
for j in ...: # 将该层循环称为 <循环2>
...
break # 终止并跳出 <循环2>
... # 继续执行 <循环1> 的语句
- \(continue\) 语句:"continue" 意为继续循环,执行该语句结束本次循环体的执行,并进入下一次循环。
4.2.4 else 扩展语句
for <循环变量> in <可迭代对象>:
<语句块1>
else:
<语句块2>
else 模块的语句只在正常结束循环结构时执行,该要求的两个条件:
-
对于
for是遍历了所有 <可迭代对象> 的内容而退出循环,对于while是由于 <条件表达式> 而退出循环 -
没有因为
break或return语句中断循环结构(continue不影响,因为其本身并不包括中断循环结构的作用)
4.3 异常处理结构
4.3.1 异常
程序在运行过程中出现的非正常现象,被称为异常。如:输入错误、除数为零、下标越界、处理的文件不存在等等
Python解释器会提示相关的错误,并在控制台中打印出来,可以查看错误说明对异常进行定位和修改,这一过程也俗称报错

4.3.2 异常处理结构(try...except...)
处理异常的过程:
-
抛出异常:创建一个代表异常的对象,停止当前执行路径,把异常对象提交给 Python 解释器
-
捕获异常:解释器得到异常后,层层向上传递,寻找相应的代码并处理异常
-
如果程序员编写了处理异常的代码,则将按照该代码处理异常。如果没有,则终止程序,显示 traceback 信息报错(如图)

try:
<被监控的可能引发异常的代码块>
except [<异常类型>]:
<异常处理语句块>
如果 try 结构中的语句没有异常,则不执行 except 结构中的语句,直接执行后续语句
如果有异常,则立即结束 try 结构,不再运行 try 结构内的后续代码,跳转到 <异常类型> 相匹配的 except 语句,进行异常处理,然后再执行后续语句
<异常类型> 可以缺省,表示任意类型的异常。即只要有异常出现,就执行 except 模块的代码块
4.3.3 多类型异常处理结构(try...多个except...)
try:
<被监控的可能引发异常的代码块>
except <异常类型 1>:
<处理 Exception1 的语句块>
except <异常类型 2>:
<处理 Exception2 的语句块>
...
except [BaseException as e]:
<处理 Exception1 的语句块>
该结构主要用于针对可能出现的不同类型的异常进行不同的处理,逻辑上类似于 if...elif...else,原理如下:
-
监控
try结构下代码,如果出现异常,立即结束try结构,不再运行try结构内的后续代码 -
出现异常后跳转到第一个
except结构,判断发生的异常类型与该except结构要求的异常类型是否一致:如果一致,则执行该except结构下的异常处理语句块,完成后跳出try...多个except结构。如果不一致,则按顺序跳转到下一个except结构,重复该步骤 -
最后我们通常写一个
except:或者except BaseException as e:语句,类似于else的功能。如果前面所有的except要求的异常类型都与我们实际发生的异常类型不符合,则可以跳转到这个结构中,处理该异常,如:try: <被监控的可能引发异常的代码块> except <异常类型 1>: <处理 Exception1 的语句块> except <异常类型 2>: <处理 Exception2 的语句块> ... except BaseException as e: print(e)如果发生的异常不被包含在前面所有的
except结构中,则其会被归入最后一句的 BaseException 类型中(该类型涵盖所有异常,见上关于异常分类的图),执行最后一个except模块,并且,我们将该异常赋值给了变量 e,我们可以输出 e 来得知该异常的类型
4.3.3 else 扩展语句
try:
<被监控的可能引发异常的代码块>
except [<异常类型>]:
<异常处理语句块>
else:
<语句块>
原理:如果 try 结构内代码出现异常,则执行 except 处理异常,不执行 else 结构下内容。只有 try 结构内代码正常运行完之后才会执行 else 结构下内容
根据原理,如果有的代码内容只有在 try 结构正常结束后才应该被运行,那么他就应该被写进 else 中。举一个通俗的例子:在吃饼干的过程中,分为 “拿起饼干” 和 “把饼干放进嘴里” 两个过程。如果在 “拿起饼干” 的过程中出现了 “饼干掉到地上” 的异常,那么下一步应该进行 “捡起饼干扔进垃圾桶”,而不进行 “把饼干放进嘴里” 的过程。只有在没有发生 “饼干掉到地上” 的异常时,才会进行 “把饼干放进嘴里” 的过程。这给吃饼干的过程用 try...except...else 结构的伪代码来表示就是:
try:
拿起饼干
except 饼干掉到地上:
捡起饼干扔进垃圾桶
else:
把饼干放进嘴里
4.4 random 库
randint(a, b):生成一个 \([a, b]\) 的随机整数
uniform(a, b):生成一个 \([a, b]\) 的随机小数
choice(seq):从序列类型对象(如列表)中随机返回一个元素
getrandbits(k):生成一个 k 位长度的随机整数(位数是二进制位数)
randrange(start, stop[, step]):生成成一个 \([start, stop)\) 步长为 \(step\) 的随机整数
shuffle(seq):将序列类型对象中的元素随机打乱排列,返回打乱后的序列
sample(seq, k):从序列类型对象中随机选取 \(k\) 个元素并随机排列,以列表形式返回

浙公网安备 33010602011771号