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 模块的语句只在正常结束循环结构时执行,该要求的两个条件:

  1. 对于 for 是遍历了所有 <可迭代对象> 的内容而退出循环,对于 while 是由于 <条件表达式> 而退出循环

  2. 没有因为 breakreturn 语句中断循环结构(continue 不影响,因为其本身并不包括中断循环结构的作用)

4.3 异常处理结构

4.3.1 异常

程序在运行过程中出现的非正常现象,被称为异常。如:输入错误、除数为零、下标越界、处理的文件不存在等等

Python解释器会提示相关的错误,并在控制台中打印出来,可以查看错误说明对异常进行定位和修改,这一过程也俗称报错

img

4.3.2 异常处理结构(try...except...)

处理异常的过程:

  1. 抛出异常:创建一个代表异常的对象,停止当前执行路径,把异常对象提交给 Python 解释器

  2. 捕获异常:解释器得到异常后,层层向上传递,寻找相应的代码并处理异常

  3. 如果程序员编写了处理异常的代码,则将按照该代码处理异常。如果没有,则终止程序,显示 traceback 信息报错(如图)

img

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,原理如下:

  1. 监控 try 结构下代码,如果出现异常,立即结束 try 结构,不再运行 try 结构内的后续代码

  2. 出现异常后跳转到第一个 except 结构,判断发生的异常类型与该 except 结构要求的异常类型是否一致:如果一致,则执行该 except 结构下的异常处理语句块,完成后跳出try...多个except结构。如果不一致,则按顺序跳转到下一个 except 结构,重复该步骤

  3. 最后我们通常写一个 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\) 个元素并随机排列,以列表形式返回

posted @ 2025-06-24 16:23  AyaMomizi  阅读(31)  评论(0)    收藏  举报