6.控制语句

我们在前面学习的过程中,都是很短的示例代码,没有进行复杂的操作。现在,我们将开始学习流程控制语句。

前面学习的变量、数据类型(整数、浮点数、布尔)、序列(字符串、列表、元组、字 典、集合),可以看做是数据的组织方式。

数据可以看做是“砖块”!流程控制语句是代码的组织方式,可以看做是“混凝土”。一个完整的程序,离不开“砖块”,也离不开“混凝土”。他们的组合,才能让我们建立从小到“一个方法”,大到“操作系统”,这样各种各样的“软件”。

1 选择结构

选择结构通过判断条件是否成立,来决定执行哪个分支。选择结构有多种形式,分为:单分支、双分支、多分支。流程图如下:

images/6.控制语句/image-20220629180610386.png

images/6.控制语句/image-20220629180633505.png

1.1 单分支选择结构

if 语句单分支结构的语法形式如下:

if 条件表达式:
	语句/语句块

其中:

  1. 条件表达式:可以是逻辑表达式、关系表达式、算术表达式等等。
  2. 语句/语句块:可以是一条语句,也可以是多条语句。多条语句,缩进必须对齐一致。

案例:输入一个数字,小于 10,则打印这个数字

#%%

num = int(input('输入一个数字:'))

if num < 10:
    print(num)

images/6.控制语句/image-20220629182054348.png

images/6.控制语句/Snipaste_2022-06-29_18-21-10.png

1.2 条件表达式详解

在选择和循环结构中,条件表达式的值为 False 的情况如下:

False、0、0.0、空值 None、空序列对象(空列表、空元祖、空集合、空字典、空字符串)、空 range 对象、空迭代对象。

其他情况,均为 True。这么看来,Python 所有的合法表达式都可以看做条件表达式,甚至包括函数调用的表达式。

# 整数作为条件表达式
if 3:
    print("ok")

# 列表作为条件表达式,由于为空列表,是 False
a = []
if not a:
    print("空列表,False")

# 非空字符串,是 True
s = "False"
if s:
    print("非空字符串,是 True")

c = 9
if 3 < c and c < 20:
    print("3<c and c<20")

# 大小于号可以连续使用
if 3 < c < 20:
    print("3<c<20")

images/6.控制语句/Pasted-image-20250926225748.png

条件表达式中,不能有赋值操作符“=”

在 Python 中,条件表达式不能出现赋值操作符 =,避免了其他语言中经常误将关系运算符 == 写作赋值运算符 = 带来的困扰。如下代码将会报语法错误:

if 3 < c and (c=20):
    print("赋值符不能出现在条件表达式中")

images/6.控制语句/Pasted-image-20250926225840.png

1.3 双分支选择结构

双分支结构的语法格式如下:

if 条件表达式:
	语句 1/语句块 1
else:
	语句 2/语句块 2

案例:输入一个数字,小于 10,则打印该数字;大于 10,则打印“数字太大”。

num = input("输入一个数字:")

if int(num) < 10:
    print(num)
else:
    print("数字太大")

images/6.控制语句/Pasted-image-20250926225946.png
images/6.控制语句/Pasted-image-20250926225958.png

三元条件运算符

Python 提供了三元运算符,用来在某些简单双分支赋值情况。

三元条件运算符语法格式如下:

条件为真时的值 if (条件表达式) else 条件为假时的值

上一个案例代码,可以用三元条件运算符实现:

num = input("请输入一个数字:")

print(num if int(num) < 10 else "数字太大")

images/6.控制语句/Pasted-image-20250926230058.png

1.4 多分支选择结构

多分支选择结构的语法格式如下:

if 条件表达式 1:
	语句 1/语句块 1
elif 条件表达式 2:
	语句 2/语句块 2
	.
	.
	.
elif 条件表达式 n:
    语句 n/语句块 n
[else:
	语句 n+1/语句块 n+1
]

注意
计算机行业,描述语法格式时,使用中括号 `[]` 通常表示可选,非必选。

images/6.控制语句/image-20220629185118258.png

多分支结构,几个分支之间是有逻辑关系的,不能随意颠倒顺序。

案例:输入一个学生的成绩,将其转化成简单描述:不及格(小于 60)、及格(60-79)、良好(80-89)、优秀(90-100)。

方法 1:使用完整的条件表达。

score = int(input("请输入分数:"))
grade = ''

if score < 60:
    grade = "不及格"
if 60 <= score < 80:
    grade = "及格"
if 80 <= score < 90:
    grade = "良好"
if 90 <= score <= 100:
    grade = "优秀"

print(f"分数是{score},等级是{grade}")

每个分支都使用了独立的、完整的判断,顺序可以随意挪动,而不影响程序运行。

images/6.控制语句/Pasted-image-20250926230523.png

方法 2:利用多分支结构。

score = int(input("请输入分数:"))
grade = ''

if score < 60:
    grade = "不及格"
elif score < 80:
    grade = "及格"
elif score < 90:
    grade = "良好"
elif score <= 100:
    grade = "优秀"

print(f"分数是{score},等级是{grade}")

images/6.控制语句/Pasted-image-20250926230635.png

注意
多分支结构,几个分支之间是有逻辑关系的,不能随意颠倒顺序。
> > ```python > score = int(input("请输入分数:")) > grade = '' > > if score <= 100: > grade = "优秀" > elif score < 60: > grade = "不及格" > elif score < 80: > grade = "及格" > elif score < 90: > grade = "良好" > > print(f"分数是{score},等级是{grade}") > ``` > > ![images/6.控制语句/Pasted-image-20250926230849.png](https://img2024.cnblogs.com/blog/3786934/202604/3786934-20260411015933283-1924007650.png)

案例:已知点的坐标 (x,y),判断其所在的象限。

x = int(input("请输入 x 坐标:"))
y = int(input("请输入 y 坐标:"))

if x == 0 and y == 0:
    print("原点")
elif x == 0:
    print("y 轴")
elif y == 0:
    print("x 轴")
elif x > 0 and y > 0:
    print("第一象限")
elif x < 0 < y:
    print("第二象限")
elif x < 0 and y < 0:
    print("第三象限")
else:
    print("第四象限")

images/6.控制语句/Pasted-image-20250926231116.png

1.5 选择结构嵌套

选择结构可以嵌套,使用时一定要注意控制好不同级别代码块的缩进量,因为缩进量决定了代码的从属关系。

语法格式如下:

if 表达式 1:
    语句块 1
    if 表达式 2:
    	语句块 2
	else:
    	语句块 3
else:
	if 表达式 4:
		语句块 4

案例:输入一个分数。分数在 0-100 之间。90 以上是 A 以上是 B,70 以上是 C,60 以上是 D。60 以下是 E。

score = int(input("请输入一个在 0-100 之间的数字:"))
grade = ""

if score > 100 or score < 0:
    score = int(input("输入错误!请重新输入一个在 0-100 之间的数字:"))
else:
    if score >= 90:
        grade = "A"
    elif score >= 80:
        grade = 'B'
    elif score >= 70:
        grade = 'C'
    elif score >= 60:
        grade = 'D'
    else:
        grade = 'E'

print(f"分数为{score},等级为{grade}")

images/6.控制语句/Pasted-image-20250926231302.png

或者也可以用下面代码更少的方法。不过,需要大家思考为什么这么写了。

# 或者也可以用下面代码更少的方法。不过,需要大家思考为什么这么写了
score = int(input("请输入一个在 0-100 之间的数字:"))
degree = "ABCDE"
num = 0

if score > 100 or score < 0:
    score = int(input("输入错误!请重新输入一个在 0-100 之间的数字:"))
else:
    num = score // 10
    if num < 6:
        num = 5

print(f"分数是{score},等级是{degree[9 - num]}")

images/6.控制语句/Pasted-image-20250926231445.png

2 循环结构

2.1 什么是循环

现实生活中,也有很多循环的应用场景:

  1. 食堂阿姨打菜:接过顾客的餐盘 ——> 询问菜品 ——> 打菜 ——> 递回餐盘,重复以上过程,直到所有顾客的菜都打完了。
  2. 快递员送快递:查看送件地址 ——> 赶往目的地 ——> 电话告知收件人 ——> 收件人签收 ——> 交快递件,重复以上过程,直到所有需要送的快递都处理完了。
  3. 公交司机……
  4. 作业流程……

以上场景都有一个共同的特点:有条件重复地做一件事,每一次做的事情不同但类似。

程序是为了解决实际问题的,实际问题中存在着重复动作,那么程序中也应该有相应的描述,这就是循环

2.2 循环的作用

思考
假如我有个女朋友,有一天我们闹矛盾生气了,女朋友说:道歉,说 100 遍“老婆大人,我错了”。这个时候程序员会怎么做?

100 遍 `print("老婆大人,我错了")`
思考
这样做太麻烦了,有没有更好的办法呢?我们难道 print 输出语句要复制粘贴 100 次嘛?

其实不用这么麻烦,以上输出代码中有很多重复的地方,我们只要重复执行 100 次相同的代码即可,这就是循环!
思考
循环的作用是什么?

**让代码高效的重复执行。**

循环结构用来重复执行一条或多条语句。表达这样的逻辑:如果符合条件,则反复执行循环体里的语句。在每次执行完后都会判断一次条件是否为 True,如果为 True 则重复执行循环体里的语句。图示如下:

images/6.控制语句/image-20220629192027744.png

循环体里面的语句至少应该包含改变条件表达式的语句,以使循环趋于结束;否则,就会变成一个死循环。

2.3 循环的种类

在 Python 中,循环一共分为两大类:while 循环与 for 循环

思考
while 循环和 for 循环如何选择呢?

1. 对于**循环次数已知**的情况或**遍历元素**,建议使用 for 循环。
> > 2. 对于**循环次数未知**的情况或**死循环**,建议使用 while 循环。

images/6.控制语句/image-20210309100103002.png

2.4 while 循环

while 循环的语法格式如下:

while 条件表达式:
    循环体语句

1、while 循环的基本语法

# 1. 定义一个计数器(初始化一个计数器)
i = 0或1
# 2. 编写while循环结构
while 循环条件(判断 计数器 是否达到了目标位置):
	循环体1
	循环体2
	...
	# 3. 在循环内部更新计数器
	i = i + 1 或 i += 1
普及小知识
在计算机程序中,计数器大部分都是从 0 开始的。

总结:while 循环三步走:

  1. 初始化计数器
  2. 编写循环条件(判断计数器是否达到了目标位置)
  3. 在循环内部更新计数器

while 循环入门案例:使用 while 循环,循环输出 100 遍“老婆大人,我错了”。

# 1. 初始化计数器
i = 0
# 2. 编写循环条件(判断计数器是否达到了100)
while i < 100:
    print('老婆大人,我错了')
    # 3. 在循环体内部更新计数器
    i += 1

images/6.控制语句/Pasted-image-20250926235902.png

2、while 循环的执行流程

建议大家使用 Debug 调试工具,查看 while 循环的运行流程。

# 1. 初始化计数器
i = 0
# 2. 编写循环条件(判断计数器是否达到了100)
while i < 100:
    print('老婆大人,我错了')
    # 3. 在循环体内部更新计数器
    i += 1

下断点,开始 Debug 调试:

images/6.控制语句/image-20210309103001017.png

  1. 代码都是顺序执行,首先执行到第 2 行,对变量 i 进行赋值操作,初始值为 0。
  2. 当程序遇到 while 循环时,首先要把我们的计数器与循环条件进行比较 i < 100,如果条件成立,则进入循环内部,执行内部代码。
  3. 在循环体内部,针对本次循环进行计数器更新操作 i = i + 1i += 1
  4. 更新完毕后,把更新后的计数器与循环条件再次进行比较 i < 100,如果条件成立,继续进入循环内部,执行内部代码。
  5. ……
  6. 直到,i 更新后结果为 100 时,再次进行循环条件判断,发现不满足,则整个 while 循环结束。

while 循环流程图:

images/6.控制语句/image-20210309103649130.png

3、while 循环案例

案例 1:使用 while 循环求 1~100 的和。

分析:定义一个 while 循环,让其可以帮助我们计算 1 + 2 + 3 + 4 + 5 … + 100。

结果:5050

大问题拆解为小问题:

  1. 使用 while 循环,循环 100 次
# 第一步:初始化计数器
i = 1
# 第二步:编写循环条件
while i <= 100:
    print(i)  # 1 2 3 4 5 6 7 8 9 10...
    # 第三步:更新计数器的值
    i += 1
  1. 在循环体内部,累计求和
# 第四步:定义一个变量,用于得到最终的运算结果
result = 0
# 第五步:想办法,让 result = 变量i累加后的结果
  1. 最终代码
# 第一步:初始化计数器
i = 1
# 第四步:定义一个 result 变量,用于接收累加后的结果
result = 0
# 第二步:编写循环条件
while i <= 100:
    # 第五步:循环累加变量i
    result += i
    # 第三步:更新计数器的值
    i += 1
print(f'1~100 累加后的结果:{result}')

images/6.控制语句/Pasted-image-20250927000349.png

☆ 首先定义变量 i 和变量 result,进行初始化赋值。

☆ 判断变量 i 是否满足循环条件,如果满足循环条件,则进入到循环体内部,执行内部代码。

思考:如何让变量 i 进行累加,然后赋予给 result。

result = i

第一次循环式,i = 1result = 0,如果想获取累加的结构,则 result = result + i

result = 0 + 1

计数器更新,i += 1,i 变成 2,然后 i <= 100,继续执行循环内部代码。

result = result + i  换成数值  result = 1 + 2

依次类推:

result = result + i

简写:

result += i

案例 2:求 1~100 之间,所有偶数的和。

什么是偶数:所谓的偶数,就是能被 2 整除的数字就是偶数,数学中可以使用 2n 来表示偶数(Python 代码 => if 数值 % 2 == 0 代表它是一个偶数)。

知识点:在 while 循环中,我们还可以结合 if 进行判断。

第一步:求出 1~100 之间,所有的数。

# 初始化计数器
i = 1
# 编写循环条件
while i <= 100:
    # 将来写代码的位置
    # 更新计数器
    i += 1

第二步:在循环体中,引入 if 条件判断,判断变量 i 是否为一个偶数。

# 初始化计数器
i = 1
# 编写循环条件
while i <= 100:
    # 将来写代码的位置
    if i % 2 == 0:
        # 代表变量 i 是一个偶数
        print(i)
    # 更新计数器
    i += 1

第三步:引入 result 变量,初始值为 0,然后对第二步中得到的所有偶数进行累加。

# 初始化计数器
i = 1
# 定义 result,用于接收所有偶数的和
result = 0
# 编写循环条件
while i <= 100:
    # 将来写代码的位置
    if i % 2 == 0:
        # 代表变量 i 是一个偶数
        result += i
    # 更新计数器
    i += 1
print(f'1~100之间所有偶数的和:{result}')

images/6.控制语句/Pasted-image-20250927001112.png

4、编写循环式常见问题

i = 1
result = 0
while i <= 100:
    if i % 2 == 0:
        result += i
        i += 1
    print(f'1~100之间所有偶数的和:{result}')

images/6.控制语句/Pasted-image-20250927001218.png

问题的原因:在于 i += 1 缩进了 2 次,导致其和 if 形成了一个整体。while 循环中计数器无法更新,最终导致以上代码出现了死循环。

2.5 for 循环

1、for 循环基本语法

for 循环结构主要用于(序列 => 字符串、列表、元组、集合以及字典)类型数据的遍历(循环)操作。

for 临时变量 in 序列:
    重复执行的代码1
    重复执行的代码2

案例:使用 for 循环遍历字符串 "小龙女"

str1 = '小龙女'  
for i in str1:  
    print(i)

images/6.控制语句/Pasted-image-20250927001318.png

使用 Debug 调试以上代码可知:for 循环功能非常强大,可以自动判断序列的长度,长度为多少,则 for 循环就循环多少次。每次循环时,系统会自动将序列中的每个元素赋值给变量 i,赋值完成后,for 循环内部会自动更新计数器,向后移动一位,继续循环,直至元素全部循环结束。

2、可迭代对象

Python 包含以下几种可迭代对象:

  1. 序列。包含:字符串、列表、元组
  2. 字典、集合
  3. 迭代器对象(iterator)
  4. 生成器函数(generator)
  5. 文件对象

我们已经在前面学习了序列、字典等知识,迭代器对象和生成器函数将在后面进行详解。接下来,我们通过循环来遍历这几种类型的数据。

案例 1:遍历字符串中的字符。

for x in "Hello":
    print(x)

images/6.控制语句/Pasted-image-20250927001519.png

案例 2:遍历字典。

d = {'name': 'gaoqi', 'age': 18, 'address': '西三旗 001 号楼'}
# 遍历字典所有的 key
for x in d:
    print(x)
print('#################')

# 遍历字典所有的 key
for x in d.keys():
    print(x)
print('#################')

# 遍历字典所有的 value
for x in d.values():
    print(x)
print('#################')

# 遍历字典所有的"键值对"
for x in d.items():
    print(x)

images/6.控制语句/Pasted-image-20250927001616.png

3、range 方法(函数)

Python2 range() 函数返回的是列表,而在 Python3 中 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型,所以打印的时候不会打印列表(由于我们还未学习面向对象,为了方便大家理解,你可以简单的将其理解为一个序列结构)。

主要作用:用于生成一段连续的内容,从 0 到 9。

基本语法:

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

"""
1. start: 计数从 start 开始。默认是从 0 开始。
	例如 range(5) 等价于range(0, 5)
2. stop: 计数到 stop 结束,但不包括 stop。
	例如:range(0,5) 是 [0, 1, 2, 3, 4] 没有 5
3. step:步长,默认为1。
	例如:range(0,5) 等价于 range(0, 5, 1)
"""
> range 有一个口诀:**顾头不顾尾**,包含头部信息,但是不包含尾部信息,如 range(10),则返回 0~9 之间的序列,又比如 range(0, 5) 代表返回 0 ~ 4 之间的序列。
案例:for 循环与 range 方法,使用 for 循环,循环 5 次。
for i in range(5):
    print(i)

4、for 循环案例

案例 1:使用 for 循环,求 1 ~ 100 的和。

# 定义一个变量,用于接收 1~100 的和
result = 0

# 从1开始循环,循环 100 次
for i in range(1, 101):
    result += i

print(f'1~100 的和为{result}')

images/6.控制语句/Pasted-image-20250927002110.png

案例 2:使用 for 循环,求 1 ~ 100 之间所有偶数的和。

# 定义一个变量,用于接收 1~100 之间所有偶数的和
result = 0

# 从1开始循环,循环 100 次
for i in range(1, 101):
    if i % 2 == 0:
        result += i

print(f'1~100 之间所有偶数的和为{result}')

images/6.控制语句/Pasted-image-20250927002144.png

2.6 嵌套循环

一个循环体内可以嵌入另一个循环,一般称为“嵌套循环”,或者“多重循环”。

1、循环嵌套的基本语法

编写一个简单的 while 循环结构。

# 初始化计数器
i = 0 或 i = 1
# 编写循环条件
while i < 边界值:
    循环体代码
    # 更新计数器
    i += 1

所谓的 while 嵌套循环就是在 while 循环的基础上,把循环体代码更换为一层 while 循环,就组成了 while 嵌套循环。

# 第一步:初始化外层循环计数器
i = 1
# 第二步:编写外层循环的条件
while i <= 3:
    # 第四步:初始化内层循环计数器
    j = 1
    # 第五步:编写内层循环的条件
    while j <= 3:
        循环体代码
    	# 第六步:更新内层循环计数器
    	j += 1
    # 第三步:更新外层循环计数器
    i += 1

结构如下:

images/6.控制语句/image-20210309144900348.png

所谓 for 循环嵌套,就是一个 for 循环里面嵌套另外一个 for 循环的写法。

当循环结构相互嵌套时,位于外层的循环结构常简称为外层循环或外循环,位于内层的循环结构常简称为内层循环或内循环。

基本语法:

# 外层循环
for i in 序列1:
    # 内层循环
    for j in 序列2:
        循环体

2、循环嵌套的执行流程

while 循环嵌套执行流程口诀:在 while 循环嵌套的执行过程中,外层循环 1 次,内层循环 N 次。(时钟 => 分针和秒针,分针就相当于外层循环,秒针就相当于内层循环)

想具体了解 while 嵌套循环的执行流程,建议使用 Debug 调试。

循环嵌套的总次数 = 外层循环次数 * 内层循环次数

3、循环嵌套的几个案例

案例 1:打印 5 行 5 列的正方形,单元格中使用 * 号进行填充。

images/6.控制语句/image-20210309150645399.png

示例代码:

# 方法一:直接print打印
# print("*  *  *  *  *")
# print("*  *  *  *  *")
# print("*  *  *  *  *")
# print("*  *  *  *  *")
# print("*  *  *  *  *")

# 方法二:使用单层while循环
# i = 1
# while i <= 5:
#     print("*  *  *  *  *")
#     i += 1

# 方法三:使用单层while循环 + 运算符
# i = 1
# while i <= 5:
#     print("*  " * 5)
#     i += 1

# 方法四:使用while循环嵌套
i = 1  
while i <= 5:  
    # print("*  *  *  *  *")  
    j = 1  
    while j <= 5:  
        if j == 5:  
            print("*")  
        else:  
            print("*  ", end='')  
        j += 1  
    i += 1

# 方法五:使用for循环嵌套
for i in range(5):  
    for j in range(5):  
        if j == 4:  
            print("*")  
            continue  
        print('*', end='  ')  

使用 Debug 工具对 while 嵌套循环进行调试可知,在正方形案例中,外层的 while 主要用于控制行 row 信息,内层的 wihle 循环主要用于控制列信息 col。

案例 2:打印直角三角形,特征:一共有 5 行,第 1 行,有 1 列。第 2 行,有 2 列,第 3,有 3 列。

images/6.控制语句/image-20210309154835512.png

分析:如果采用 wihle 循环嵌套,外层应该循环 5 次,内层循环次数有一定的规则:

  • 第 1 行内循环执行 1 次。
  • 第 2 行内循环执行 2 次。
  • 第 3 行内循环执行 3 次。
  • 第 4 行内循环执行 4 次。
  • 第 5 行内循环执行 5 次。
# 定义外层循环计数器
i = 1
# 编写外层循环的循环条件
while i <= 5:
    # 定义内层循环计数器
    j = 1
    # 编写内层循环的循环条件
    while j <= i:
        if j == i:  
		    print("*")  
		else:  
		    print("*", end='  ')
        j += 1
    # 更新外层循环计数器
    i += 1

# for循环实现
for i in range(1, 6):
    for j in range(i):
        if j == i-1:  
		    print("*")  
		else:  
		    print("*", end='  ')

案例 3:使用 while 嵌套循环打印 9 x 9 乘法表。

images/6.控制语句/image-20210309160453980.png

第一步:使用 while 嵌套循环打印 9 行的直角三角形。

# 初始化外层循环计数器
i = 1
# 编写外层的循环条件
while i <= 9:
    # 初始化内层循环计数器
    j = 1
    # 编写内层的循环条件
    while j <= i:
        print('*', end='  ')
        # 更新内层循环的计数器
        j += 1
    print('')
    # 更新外层循环计数器
    i += 1

第二步:把小星星换成具体的数值

# 初始化外层循环计数器
i = 1
# 编写外层的循环条件
while i <= 9:
    # 初始化内层循环计数器
    j = 1
    # 编写内层的循环条件
    while j <= i:
	    if j == i:
		    print(f'{j} x {i} = {i * j}')
	    else:
	        print(f'{j} x {i} = {i * j}', end='\t')
        # 更新内层循环的计数器
        j += 1
    # 更新外层循环计数器
    i += 1

for 循环实现

for row in range(1, 10):
    for col in range(1, row + 1):
        if col == row:
            print(f'{col} x {row} = {row * col}')
        else:
            print(f'{col} x {row} = {row * col}', end='\t')

总结:外层循环主要用于控制循环的行数,内层循环用于控制列数

2.7 break 语句

break 语句可用于 while 和 for 循环,用来结束整个循环。当有嵌套循环时,break 语句只能跳出最近一层的循环。

案例:使用 break 语句结束循环。

while True:
    a = input("请输入一个字符(输入 Q 或 q 结束)")
    if a.upper() == 'Q':
        print("循环结束,退出")
        break
    else:
        print(a)

2.8 continue 语句

continue 语句用于结束本次循环,继续下一次。多个循环嵌套时,continue 也是应用于最近的一层循环。

案例:要求输入员工的薪资,若薪资小于 0 则重新输入。最后打印出录入员工的数量和薪资明细,以及平均薪资。

emp_num = 0
salary_sum = 0
salaries = []

while True:
    s = input("请输入员工的薪资(按 Q 或 q 结束):")

    if s.upper() == 'Q':
        print("录入完成,退出!!!")
        break
    if float(s) < 0:
        print("员工薪资不得小于0,请重新输入!!!")
        continue

    emp_num += 1
    salaries.append(float(s))
    salary_sum += float(s)

print(f"员工数{emp_num}")
print("录入薪资:", salaries)
print(f"平均薪资{salary_sum / emp_num}")

images/6.控制语句/Pasted-image-20250927003159.png

2.9 while 循环与 for 循环中的 else 结构

1、为什么需要在 while 循环中添加 else 结构

循环可以和 else 配合使用,else 下方缩进的代码指的是当循环正常结束之后要执行的代码

强调:只有循环正常结束时才会执行,循环非正常结束(如遇到 break 的情况),else 中的代码时不会执行的。

2、while 循环中 else 的基本语法

语法格式:

while 条件表达式:
	循环体
else:
	语句块

或者:
for 变量 in 可迭代对象:
	循环体
else:
	语句块

需求:女朋友生气了,要惩罚:连续说 5 遍“老婆大人,我错了”,如果道歉正常完毕后女朋友就原谅我了,这个程序怎么写?

# 初始化计数器
i = 0
# 编写循环条件
while i < 5:
    print('老婆大人,我错了')
	# 更新计数器
    i += 1
# 循环结束后,女朋友就原谅我了
print('好开森,女朋友原谅我了...')

思考:这个 print 是不是没有循环也能执行?那我们应该如何解决呢?

答:使用 while…else 结构。

# 初始化计数器
i = 0
# 编写循环条件
while i < 5:
    print('老婆大人,我错了')
    # 更新计数器
    i += 1
# 循环结束后,女朋友就原谅我了
else:
    print('好开森,女朋友原谅我了...')

images/6.控制语句/Pasted-image-20250927003515.png

3、break 关键字对 while…else 结构的影响

需求:女朋友生气,要求道歉 5 遍:老婆大人,我错了。道歉到第三遍的时候,媳妇埋怨这一遍说的不真诚,是不是就是要退出循环了?这个退出有两种可能性:

  1. 更生气,不打算原谅,也不需要道歉了,程序如何书写?
  2. 只一遍不真诚,可以忍受,继续下一遍道歉,程序如何书写?
# 初始化计数器
i = 0
# 编写循环条件
while i < 5:
    if i == 2:
        print('这遍说的不够真诚')
        break
    print('老婆大人,我错了')
    # 更新计数器
    i += 1
# 循环结束后,女朋友就原谅我了
else:
    print('好开森,女朋友原谅我了...')

images/6.控制语句/Pasted-image-20250927003605.png

由运行结果可知,如果我们在 while 循环中,使用了 break,一旦 break 语句执行了,则 else 语句则不会输出。

4、continue 关键字对 while…else 结构的影响

# 初始化计数器
i = 0
# 编写循环条件
while i < 5:
    if i == 2:
        i += 1
        print('这遍说的不够真诚')
        continue
    print('老婆大人,我错了')
    # 更新计数器
    i += 1
# 循环结束后,女朋友就原谅我了
else:
    print('好开森,女朋友原谅我了...')

images/6.控制语句/Pasted-image-20250927003710.png

由运行结果可知,如果我们在 while 循环中,使用了 continue,continue 语句执行了,else 语句也会输出。

5、for 循环结构中的 else 结构

基本语法:

for 临时变量 in 序列:
    循环体
else:
    当for循环正常结束后,返回的代码

6、break 关键字对 for…else 结构的影响

str1 = 'Hello'
for i in str1:
    if i == 'e':
        print('遇e不打印')
        break
    print(i)
else:
    print('循环正常结束之后执行的代码')

images/6.控制语句/Pasted-image-20250927003839.png

7、continue 关键字对 for…else 结构的影响

str1 = 'Hello'
for i in str1:
    if i == 'e':
        print('遇e不打印')
        continue
    print(i)
else:
    print('循环正常结束之后执行的代码')

images/6.控制语句/Pasted-image-20250927003913.png

2.10 循环代码优化

虽然计算机越来越快,空间也越来越大,我们仍然要在性能问题上“斤斤计较”。编写循环时,遵守下面三个原则可以大大提高运行效率,避免不必要的低效计算:

  1. 尽量减少循环内部不必要的计算
  2. 嵌套循环中,尽量减少内层循环的计算,尽可能向外提。
  3. 局部变量查询较快,尽量使用局部变量
# 循环代码优化测试
import time

start = time.time()

for i in range(1000):
    result = []
    for m in range(10000):
        result.append(i * 1000 + m * 100)

end = time.time()
print("未优化耗时:{0}".format((end - start)))

# 优化后
start2 = time.time()

for i in range(1000):
    result = []
    c = i * 1000
    for m in range(10000):
        result.append(c + m * 100)

end2 = time.time()
print("优化后耗时:{0}".format((end2 - start2)))

images/6.控制语句/Pasted-image-20250927004049.png

其他优化手段

  1. 连接多个字符串,使用 join() 而不使用 +
  2. 列表进行元素插入和删除,尽量在列表尾部操作。

2.11 使用 zip() 并行迭代

我们可以通过 zip() 函数对多个序列进行并行迭代,zip() 函数在最短序列“用完”时就会停止。

names = ("小龙女", "赵敏", "周芷若", "黄蓉")
ages = (18, 16, 20, 25)
jobs = ("古墓派掌门", "郡主", "峨眉派掌门")

for name, age, job in zip(names, ages, jobs):
    print("{0}--{1}--{2}".format(name, age, job))

images/6.控制语句/Pasted-image-20250927004347.png

3 推导式生成序列

3.1 什么是推导式

推导式 comprehensions(又称解析式),是 Python 的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列(一个有规律的列表或控制一个有规律列表)的结构体。共有三种推导:列表推导式集合推导式字典推导式

3.2 为什么需要推导式

案例:创建一个 0-9 的列表。

while 循环:

list1 = []

# 编写 for 循环
for i in range(0, 10):
    list1.append(i)

print(list1)

images/6.控制语句/Pasted-image-20250927004559.png

for 循环:

list1 = []

# 编写 for 循环
for i in range(0, 10):
    list1.append(i)

print(list1)

images/6.控制语句/Pasted-image-20250927004559.png

思考
我们能不能把以上代码简化为一行代码搞定这个程序呢?

可以,使用推导式

3.3 列表推导式

基本语法:

变量名 = [表达式 for 变量 in 列表]
变量名 = [表达式 for 变量 in 列表 if 条件]

案例:定义 0-9 之间的列表。

list1 = []
for i in range(10):
    list1.append(i)
print(list1)

列表推导式:

list1 = [i for i in range(10)]

print(list1)

images/6.控制语句/Pasted-image-20250927004559.png

执行原理:[i for i in range(10)]

列表推导式先运行表达式右边的内容:

当第一次遍历时:i = 0,其得到变量i的结果后,会放入最左侧的变量i中,这个时候列表中就是[0]
当第二次遍历时:i = 1,其得到变量i的结果后,会追加最左侧的变量i中,这个时候列表中就是[0, 1]
...
当最后一次遍历时:i = 9,其得到变量i的结果后,会追加最左侧的变量i中,这个时候列表中就是[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

3.4 列表推导式 + if 条件判断

在使用列表推导式时候,我们除了可以使用 for 循环,其实我们还可以在其遍历的过程中,引入 if 条件判断。

变量 = [表达式 for 临时变量 in 序列 if 条件判断]

等价于

for 临时变量 in 序列:
    if 条件判断

案例:生成 0-9 之间的偶数(i % 2 == 0)序列。

list1 = [i for i in range(10) if i % 2 == 0]

print(list1)

images/6.控制语句/Pasted-image-20250927004929.png

3.5 for 循环嵌套列表推导式

for 临时变量 in range(n):
    for 临时变量 in range(n):

基本语法:

变量 = [表达式 for 临时变量 in 序列 for 临时变量 in 序列]

案例:创建列表 => [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

原生代码:for 循环嵌套。

list1 = []

# 外层循环
for i in range(1, 3):
    # 内层循环
    for j in range(0, 3):
        tuple1 = (i, j)
        list1.append(tuple1)

print(list1)

images/6.控制语句/Pasted-image-20250927005027.png

列表推导式:

list1 = [(x, y) for x in range(1, 3) for y in range(3)]

print(list1)

images/6.控制语句/Pasted-image-20250927005027.png

3.6 字典推导式

思考:有如下两个列表,如何快速合并为一个字典?

list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'male']

person = {'name':'Tom', 'age':20, 'gender':'male'}

答:使用字典推导式。

基本语法:

① 字典推导式列表推导式思想的延续,语法差不多,只不过产生的是字典而已。

② 字典推导式格式:

变量 = {key: value for key, value in 序列}

字典推导式作用:快速合并列表为字典或提取字典中目标数据

案例 1:创建一个字典:字典 key 是 1-5 数字,value 是这个数字的 2 次方。

dict1 = {1:1, 2:4, 3:9, 4:16, 5:25}

dict1 = {i: i ** 2 for i in range(1, 6)}

print(dict1)

images/6.控制语句/Pasted-image-20250927005326.png

案例 2:把两个列表合并为一个字典。

list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'male']
# 结果:person = {'name':'Tom', 'age':20, 'gender':'male'}

person = {list1[i]: list2[i] for i in range(len(list1))}

print(person)

images/6.控制语句/Pasted-image-20250927005410.png

或者使用 zip() 函数。

list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'male']

person = {key: value for key, value in zip(list1, list2)}

print(person)

images/6.控制语句/Pasted-image-20250927005410.png

案例 3:提取字典中目标数据。

counts = {'MBP': 268, 'HP': 125, 'DELL': 201, 'Lenovo': 199, 'ACER': 99}

# 需求:提取上述电脑数量大于等于200的字典数据
counts = {key: value for key, value in counts.items() if value >= 200}

print(counts)

images/6.控制语句/Pasted-image-20250927005652.png

3.7 集合推导式

集合推导式跟列表推导式非常相似,唯一区别在于用 {} 代替 []

思考
为什么需要集合推导式,列表推导式不香么?

集合的最大特点就是去重。

需求:创建一个集合,数据为下方列表的 2 次方。

list1 = [1, 1, 2]
set1 = {1, 4}

推导式:

list1 = [1, 1, 2]

set1 = {i ** 2 for i in list1}

print(set1)

images/6.控制语句/Pasted-image-20250927005850.png

3.8 生成器推导式(生成元组)

很多同学可能会问:“都有推导式,元组有没有?”,能不能用小括号呢?

res = (x for x in range(1, 100) if x % 9 == 0)

print(res)

images/6.控制语句/Pasted-image-20250927010020.png

我们发现提示的是“一个生成器对象”。显然,元组是没有推导式的。

一个生成器只能运行一次。第一次迭代可以得到数据,第二次迭代发现数据已经没有了。

gnt = (x for x in range(1, 100) if x % 9 == 0)
for x in gnt:
    print(x, end=' ')
print()
print('##############')

for x in gnt:
    print(x, end=' ')

images/6.控制语句/Pasted-image-20250927005949.png

3.9 生成式表达式和列表解析式对比

生成式表达式 列表解析式
延迟计算 立即计算
返回可迭代对象迭代器,可以迭代 返回可迭代对象列表,不是迭代器
只能迭代一次
可反复迭代
  1. 计算方式
    • 生成器表达式延迟计算。
    • 列表解析式立即计算。
  2. 内存占用
    • 单从返回值本身来说,生成器表达式省内存,列表解析式返回新的列表。
    • 生成器没有数据,内存占用极少,而且使用的时候,是一个个返回数据,不会返回所有元素而立即占用大量内存。
    • 列表解析式构造新的列表需要立即占用掉内存。
  3. 计算速度
    • 单看计算时间看,生成器表达式耗时非常短,列表解析式耗时长。
    • 但生成器本身并没有返回任何值,只返回了一个生成器对象。
    • 列表解析式构造并返回了一个新的列表。

3.10 补(了解)

  1. 序列:
    常见的序列有:listtuplestrbytesbytearray

    字节串 bytes,字节数组 bytearray 是二进制数据组成的序列,其中每个元素由 8bit 二进制组成。

  2. 字节数组 bytearray
    可变的字节序列,相当于 bytes 的可变版本。

posted @ 2026-04-11 01:59  挖掘鱼  阅读(3)  评论(0)    收藏  举报