西安科技大学

安全工程专业课程

安全仿真与模拟基础


金洪伟 & 闫振国 & 王延平

西安科技大学安全科学与工程学院


返回目录⇡

如何浏览?

  1. 从浏览器地址栏打开 https://zimo.net/aqmn/
  2. 点击章节列表中的任一链接,打开相应的演示文稿;
  3. 点击链接打开演示文稿,使用空格键或方向键导航;
  4. f键进入全屏播放,再按Esc键退出全屏;
  5. Alt键同时点击鼠标左键进行局部缩放;
  6. Esco键进入幻灯片浏览视图。

请使用最新版本浏览器访问此演示文稿以获得更好体验。

第 2 部分  Python 基础

第 3 章  流程控制语句

目 录

  1. 程序结构
  2. if 语句
  3. match 语句
  4. while 语句
  5. for 语句
  6. 跳转语句
  7. pass 语句
  8. 示例

1. 程序结构

1.1 语句

语句(Statement)是指令式编程语言中最小的独立元素,表达程序要执行的一些动作。语句是程序段(一个代码“块”)的组成单位。一条语句可以是一个表达式或某个带有关键字的结构,例如 ifwhilefor。一般将 Python 的语句分为简单语句复合语句

简单语句
由一个单独的逻辑行构成的语句。
复合语句
包含其它语句(语句组)的语句,它们会以某种方式影响或控制所包含其它语句的执行。通常,复合语句会跨越多行,虽然在某些简单形式下整个复合语句也可能包含于一行之内。

像 C、Java 语言一样,Python 以分号 ; 作为语句结束的标识,但 Python 中句末的分号可以省略,并且经常省略。

1.1 语句

Python 的简单语句包括表达式语句、赋值语句、assert 语句、pass 语句、del 语句、return 语句、yield 语句、raisebreak 语句、continue 语句、import 语句、future 语句、global 语句、nonlocal 语句。

多条简单语句也可以存在于同一行内并以分号分隔,如下所示:


            # 习惯写法
            a = 2
            b = 3
            print(a ** b)  # 8
            
            # 也可以在一行内写多条语句,但不推荐这样
            a = 2; b = 3; print(a ** 3)  # 8
        

1.1 语句

也可以将一个简单语句分多行书写。如同字符串中可以使用 \<换行> 来消除换行,同样可以使用 \ 作为行连续符,将


            s = '我' + \
                '有一个' + \
                '梦'
            print(s)  # 我有一个梦
        

另外,如果语句中包含 ( )[ ]{ } 这类括号,在括号内不需要使用 \ 可以直接换行:


            weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
                        'Friday', 'Saturday', 'Sunday']
        

1.1 语句

复合语句的结构

复合语句由一个或多个子句组成,每个子句包含一个句头和一个句体。每个子句头以一个关键字开始并以一个冒号结束。子句体可以包含一行或多行,经常和句头放在不同行,并缩进书写。如右图所示。

Python 的复合语句包括 if 语句、match 语句、while 语句、for 语句、try 语句、with 语句、函数定义、类定义、协程。

1.1 语句

缩进在 Python 中是非常重要的。其他语言,如 C、Java、JavaScript,缩进只具有提高可读性的作用,编译器并不关心这些缩进。但在 Python 中,用缩进来表示语句块(或称代码块)的范围,并列的语句具有相同的缩进。

可以使用任意个数的空格和水平制表符进行缩进,但习惯上用 4 个空格进行缩进,即行首的空格数是 4 的倍数。当下一行的缩进少了一级时,语句块在此行结束。


            s = 'Hello'
            if s != '':
                s += ', world!'
                print(s)  # if 语句块在此行结束
            print(s)  # Hello
        

1.2 结构化编程

结构化编程(Structured programming)是一种编程范式。它通过大量使用选择结构(if 语句)、循环结构(whilefor 语句)、块结构、子程序这些结构化的控制流程,来改善计算机程序的明晰性、质量以及开发时间,并且避免写出面条式代码(指源代码的控制流程复杂、混乱而难以理解)

控制流程(Control flow)是指令式编程语言中,语句、指令或函数调用被执行或求值的顺序。

1.2 结构化编程

根据结构化编程理论,所有的程序可由如下四种控制流程(或称控制结构)组成:

  • 顺序结构(Sequence):语句或子程序按预先排好的顺序逐次执行。
  • 选择结构(Selection):通过判断条件是否成立,来决定执行哪个分支。Python 通过 if...elif...else 语句实现选择结构。
  • 循环结构(Iteration):一直执行某一段程序,直到满足特定条件,或是一集合体中的所有元素均已处理过。Python 通过 whilefor 语句实现循环结构。
  • 递归结构(Recursion):一条语句通过重复调用自身来执行,直到满足终止条件。递归结构与循环结构类似,但可能会更高效,且在计算机实现上有所不同。

1.2 结构化编程

2. if 语句

if 语句是选择语句之一,其完整的形式如下:


            if 表达式1:
                语句块1
            elif 表达式2:
                语句块2
            elif 表达式3:
                语句块3
            ...
            else:
                语句块n
        

2. if 语句

if 语句具有如下特征:

  • if 语句可以具有多个分支,第一个分支的句头用 if 关键字标识,最后一个分支用 else 标识,中间的各个分支都用 elif(else if 的缩写)标识。
  • 除了最后的 else 分支外,其他每个分支都在句头有一个条件表达式。
  • 当遇到第一个表达式的求值结果为 True 时,则执行该分支对应的语句块(句体),其他分支不被执行。
  • 若所有分支的表达式都为 False,则执行最后的 else 分支。
  • 除了第一个 if 分支,其他的 elifelse 分支都可省略。

2.1 单分支 if 语句

单分支 if 语句

若同时省略 elifelse 分支,所得 if 语句为单分支选择语句,其形式最简单。如下所示:


                    hour = 9
                    if 7 <= hour < 11:
                        s = 'Good morning!'
                        print(s)
                

2.2 二分支 if...else 语句

二分支 if...else 语句

若省略 elif 分支,所得 if...else 语句为二分支选择语句。如下所示:


                    n = int(input('请输入一个整数:'))
                    if n % 2 == 0:
                        print(f'您输入的 {n} 是一个偶数。')
                    else:
                        print(f'您输入的 {n} 是一个奇数。')
                

2.3 多分支 if...elif...else 语句

多分支 if...elif...else 语句

可以同时具有一个 if 分支,一个 else 分支,以及一个或多个 elif 分支,所得 if...elif...else 语句为多分支选择语句。

2.3 多分支 if...elif...else 语句

根据输入的数字打印“玫瑰花语”:


            number = int(input('您想送几朵玫瑰花?'))
            if number == 1:
                print('1 朵:你是我的唯一')
            elif number == 2:
                print('2 朵:世界只有你和我')
            elif number == 3:
                print('3 朵:我爱你')
            elif number == 10:
                print('10 朵:十全十美')
            else:
                print('其他美好的愿望')
        

2.4 if 语句的嵌套

多个 if 语句也可以嵌套使用,如下所示:


            number = int(input('您想送几朵玫瑰花?'))
            if number <= 0:
                print('你必须输入一个正整数!')
            else:
                if number == 1:
                    print('1 朵:你是我的唯一')
                elif number == 2:
                    print('2 朵:世界只有你和我')
                elif number == 3:
                    print('3 朵:我爱你')
                elif number == 10:
                    print('10 朵:十全十美')
                else:
                    print('一切的美好的祝福')
        

2.5 if...else 语句的简写法

if...else 语句中每个分支中只有一个语句时,可以使用简写法。如下面的代码:


            x = 100
            if x == 100:
                print('满分')
            else:
                print('尚有提升空间')
        

可以简化为:


            x = 100
            print('满分') if x == 100 else print('尚有提升空间')  # 满分
        

这种简写法的形式为:


            <表达式为 True 时执行的语句> if <表达式> else <表达式为 False 时执行的语句>
        

2.5 if...else 语句的简写法

当需要根据一个 if...else 语句的执行结果为变量赋值时,常使用这种简化写法。如下所示:


            x = 100
            s = '满分' if x == 100 else '尚有提升空间'
            print(s)  # 满分
        

注意句末的 else 后面是 '尚有提升空间' 而不是 s = '尚有提升空间',这样整个 '满分' if x == 100 else '尚有提升空间' 就类似其他语言的三元条件运算符所形成的表达式,因此这种简写形式也称为条件表达式

3. match 语句

match 语句在 2021 年 Python 3.10 发布时加入,又可称为 match case 语句。该语句的基础形式有点像 C 语言的 switch 语句,属于另外一种选择语句。但通过复杂的模式匹配,该语句要更强大,能更方便我们控制程序流。以下是其基础形式的示例:


            match number:
                case 1:
                    print('1 朵:你是我的唯一')
                case 2:
                    print('2 朵:世界只有你和我')
                case 3:
                    print('3 朵:我爱你')
                case 10:
                    print('10 朵:十全十美')
                case _:
                    print('其他美好的愿望')
        

3. match 语句

match 语句将 match 关键字后面的表达式与每个 case 关键字后面的模式进行对比,如果找到第一个匹配(如相等)的模式,则执行该分支,剩下的分支将不再执行。

名称为 _ 的变量为通配符,它必定会匹配成功。其作用类似于 if-elif-else 语句中的 else 分支。该分支必须作为最后一个分支放置。

在一些情况下,相对于多分支的 ifmatch 语句显得更整洁。

可以使用竖线 |(意思为“或”)在一个模式中组合多个字面值,见下页示例。

3. match 语句


            cny_unit_name = '角'
            match cny_unit_name:
                case '元' | '圆' | '块':
                    cny_unit_value = 1.0
                case '角' | '毛':
                    cny_unit_value = 0.1
                case '分':
                    cny_unit_value = 0.01
                case '厘':
                    cny_unit_value = 0.001
                case '毫':
                    cny_unit_value = 0.0001
                case _:
                    cny_unit_value = 0.0
            
            possession = 3.33  # 默认以“元”为单位
            print(f'我的个人财产为 {possession / cny_unit_value:.2f} {cny_unit_name}。')
            # 我的个人财产为 33.30 角。
        

以上示例将个人资产值 possession 换算为其他人民币单位名称 cny_unit_name 对应的值。

3. match 语句

选学 >>模式的形式类似解包赋值,并可被用于绑定变量


            point = (0, 1)  # point 是一个 (x, y) 形式的元组
            match point:
                case (0, 0):
                    print("坐标原点")
                case (0, y):
                    print(f"Y={y}")  # 注意元组的第 2 个元组被绑定到变量 y 上
                case (x, 0):
                    print(f"X={x}")  # 注意元组的第 1 个元组被绑定到变量 x 上
                case (x, y):
                    print(f"X={x}, Y={y}")  # 注意元组的两个元素被绑定到 (x, y) 的两个元素上
                case _:
                    raise ValueError("不是一个点")  # 前面都无法匹配,说明 point 不是 (x, y) 形式的元组
        

使用 match 进行模式匹配还有更多高级的用法,这里不再介绍。

4. while 语句

while 是循环语句之一,其形式为:


                    while 表达式:
                        循环体
                

该语句会重复地检验表达式,当表达式为 True 时,会重复地执行循环体。以下代码将打印 Hello 5 次:


                    i = 0
                    while i < 5:
                        print('Hello')
                        i += 1
                
while 语句

注:这里在每次循环中将计数器 i 加 1 是非常有必要的,否则表达式将永远为 True,循环将无限进行下去。

4. while 语句

while 还可以像 if 语句那样带一个 else 子句,当表达式为 False 时将执行 else 子句一次。如下所示:


            i = 0
            while i < 5:
                print('Hello')
                i += 1
            else:
                print('Bye!')
        

以上代码将打印 Hello 5 次,打印 Bye! 一次。

5. for 语句

for 是另一种循环语句,其形式为:


                    for 迭代变量 in 表达式列表:
                        循环体
                

for 用于对序列(例如字符串、元组或列表)或其他可迭代对象中的元素进行迭代。表达式列表会被求值一次,并产生一个可迭代的对象。系统将依次把可迭代对象的每一项赋值给迭代变量,并执行一次循环体。当所有项被耗尽时,将终止循环。

for 语句

注:Python 的 for 语句更像 C 语言的 foreach 语句。

5. for 语句

简单示例:


            s = '我爱吃菠菜'
            for c in s:
                print(c)
        

以上代码中,字符串 s 是一个序列,将对字符串的每个元素(每个字符构成的子字符串)进行迭代。该段代码将打印:


            我
            爱
            吃
            菠
            菜
        

5. for 语句

以上代码如果要用 while 循环书写,就得这样写:


            s = '我爱吃菠菜'
            i = 0
            while i < len(s):
                print(s[i])
                i += 1
        

从以上代码可以看出,for 循环可以看作是 while 循环的简写。for 循环不用手动判断是否满足迭代条件,因此更不容易出错。当迭代的次数已提前知道时,更推荐使用 for 循环。

5. for 语句

Python 有一个内置的的 range() 函数,它返回一个 range 类型,该类型表示不可变的数字序列,通常用于在 for 循环中指定循环的次数。如下所示:


            for i in range(5):
                print(i)
        

range() 的完整形式是:


            range(stop)
            range(start, stop[, step])
        

其中,start 表示数字序列的起始值,stop 表示终止值(不包含该数本身),step 表示步长。startstep 都可以省略。当省略 start 时,默认为 0;当省略 step 时,默认为 1。step 值也可以是负整数,表示序列将递减,这时一般要求 start > stop

5. for 语句

请判断以下三个 for 语句的输出内容:


            for i in range(3, 15, 3):
                print(i)
            
            for i in range(3, 15, -3):
                print(i)
            
            for i in range(15, 3, -3):
                print(i)
        

5. for 语句

for 语句也可以嵌套使用,如下示例打印了九九乘法表


            for i in range(1, 10):
                for j in range(1, i + 1):
                    print(f'{j}×{i}={i * j}\t', end='')
                print('')
        

其输出为:


            1×1=1	
            1×2=2	2×2=4	
            1×3=3	2×3=6	3×3=9	
            1×4=4	2×4=8	3×4=12	4×4=16	
            1×5=5	2×5=10	3×5=15	4×5=20	5×5=25	
            1×6=6	2×6=12	3×6=18	4×6=24	5×6=30	6×6=36	
            1×7=7	2×7=14	3×7=21	4×7=28	5×7=35	6×7=42	7×7=49	
            1×8=8	2×8=16	3×8=24	4×8=32	5×8=40	6×8=48	7×8=56	8×8=64	
            1×9=9	2×9=18	3×9=27	4×9=36	5×9=45	6×9=54	7×9=63	8×9=72	9×9=81	
        

5. for 语句

for 语句也可以带有 else 子句,当迭代结束时,将执行从子句一次。如下所示:


            for i in range(3, 0, -1):
                print(i)
            else:
                print('发射!')
        

将打印:


            3
            2
            1
            发射!
        

6. 跳转语句

跳转语句包括 breakcontinue 语句,都只用于 whilefor 循环语句中。

  • break 语句用于跳出最近的 whilefor 循环。如果循环有可选的 else 子句,也会跳过该子句。
  • continue 语句表示继续执行循环的下一次迭代。

6. 跳转语句

以下代码的 while 语句是一个无限循环,请解释该段代码的行为:


            while True:
                greeting_word = input('请输入一个字符串:')
                match greeting_word.lower():
                    case 'hello' | 'hi':
                        print('您好!')
                    case 'good morning':
                        print('早上好!')
                    case 'bye' | 'goodbye' | '88':
                        print('再见!')
                        break
                    case _:
                        continue
                        print(greeting_word)  # 此行永远无法执行        
        

7. pass 语句

pass 语句不执行任何操作。当语法上需要一个语句,但程序不实际执行任何动作时,可以使用该语句。

在 Python 3.x 版本中,允许在可以使用表达式的任何地方使用 ...(三个连续的点号)来省略代码。该 ... 表达式也可以当做是 pass 语句的一种替代方案。


            def func1():
                pass
            
            def func2():
                ...

            x = ...
        

8. 示例

8.1 猜数字游戏

先随机生成一个 1 到 100 之间的整数,然后由玩家猜一个数并输入,提示猜测是大了还是小了。如果猜对了,打印祝贺信息并退出。


            import random
            print('***** 猜数字游戏 *****')
            secret_number = random.randrange(1, 101)
            while True:
                guess = int(input('请输入您的猜测:'))
                if guess < secret_number:
                    print('太小了!')
                elif guess > secret_number:
                    print('太大了!')
                elif guess == secret_number:
                    print('恭喜,猜中了!')
                    break            
        

8.2 判断某整数是否为回文数

所谓回文数,就是各位数字从高位到低位正序排列和从低位到高位逆序排列都是同一数值的数,如 1221、37973。请判断某个整数是否为回文数。


            num = 33799733
            num_str = str(num)
            is_palindromic = True
            for i in range(len(num_str) // 2):
                if num_str[i] != num_str[-1-i]:
                    is_palindromic = False
                    break
            if is_palindromic:
                print(f'{num} 是回文数。')
            else:
                print(f'{num} 不是回文数。')      
        

作业

  1. 通过编程打印出 1 到 100 之间所有同时能被 4 和 6 整除的整数。
  2. 根据一天不同的时间 h,可以将一天划分为多个时间段,其对应的名称和范围分别为:凌晨(1 ≤ h < 5),早上(5 ≤ h < 8),上午(8 ≤ h < 11),中午(11 ≤ h < 13),下午(13 ≤ h < 17),傍晚(17 ≤ h < 19),晚上(19 ≤ h < 23),子夜(h ≥ 23 且 h < 1)。请通过键盘输入一个 [0, 24] 之间的浮点数表示的时间(其小数部分对应一个小时内十进制的时间,如 8.75 对应的实际时间是 8:45:00),将该数重新表示为 hh:mm:ss 这样“时:分:秒”的形式,同时输出该时间所对应的时间段名称。

作业

  1. 对于下面一段文字:

    西安科技大学历史悠久,底蕴深厚。学校办学历史可以追溯到1895年成立的北洋大学工学院采矿冶金科,1938年迁并于西北工学院矿冶系,1957年并入西安交通大学,1958年从西安交通大学分出成立西安矿业学院,是当时隶属原煤炭工业部仅有的2所5年制本科院校之一。1998年学校实行“中央与地方共建,以地方管理为主”,划转陕西省。1999年更名为西安科技学院,2003年更名为西安科技大学。

    不使用任何已有字符串方法和函数,也不用 in 运算符,判断其中有几个'西安'子字符串,以类似如下形式打印结果:

    
                        序号    位置
                        1       0
                    

    上表中“序号”表示该子字符串出现的次序,从 1 开始编号,位置表示子字符串出现的起始位置。当子字符串多次出现时,自动增加表格的行数。

    注:在对字符串进行索引时,要谨防索引超过字符串长度。

作业

  1. 从键盘上输入一个整数,计算并输出其翻转后得到的整数。如 123 → 321,-123 → -321,0 → 0,120 → 21。

    注:需要先将整数转换为字符串,利用字符串的切分和拼接得到一个新的字符串,然后再将所得字符串转换为整数。

作业

要求:

  1. 将本章全部作业放在一个 安模作业02-03-学号-姓名.py 的源文件中,通过电子邮件以附件形式发给任课教师。
  2. 在源文件中以注释的形式醒目地写明本次作业对应的章编号、各个作业题的编号,并按要求写出解题思路、代码注释。
  3. 以上各题不能只有文字说明,而应同时有可执行的示例代码。
  4. 邮件标题统一用 安模作业02-03-学号-姓名 的形式。
  5. 所有关于作业的回答都以代码注释的形式写在源文件中,不需要再额外附加其他文档或图片,请保证代码执行不会发生错误。
  6. 待本次作业批改后,请通过此链接下载本次作业的参考答案。

  谢谢!

返回目录
返回首页