Python while 循环
我们先解决一个具体任务:连续完成 5 次练习,并逐次输出完成记录。如果把同一段代码复制 5 遍,次数一变就要重新修改;我们需要让程序自己重复执行。
前面学习的 if 用来判断“某段代码要不要执行”,while 则用来解决“某段代码要重复执行多少次”。本章会继续追问:次数为什么不对或停不下来?每轮结果如何累计?遇到行和列两层重复时,怎样避免手写每一行?
while 基本结构
先让“完成一次练习”的代码自动重复 5 次,再观察循环如何判断、执行和更新。
while 循环的基本语法如下:
while 条件:
条件成立时重复执行的代码写一个能够正常结束的 while 循环,通常需要考虑四个环节:
- 初始化循环变量
- 判断循环条件
- 执行循环体
- 更新循环变量
下面连续打印 5 次练习记录:
count = 1
while count <= 5:
print(f"完成第 {count} 次练习")
count += 1运行结果:
完成第 1 次练习
完成第 2 次练习
完成第 3 次练习
完成第 4 次练习
完成第 5 次练习在这段代码中:
count = 1:准备循环变量,表示从第 1 次开始count <= 5:决定循环是否继续print(...):每轮循环要完成的任务count += 1:更新循环变量,让条件逐渐接近不成立
while 每执行完一轮,都会回到条件处重新判断,而不是判断一次后一直执行。
如果把每一次判断和执行全部展开,流程如下:
如果要重复 100 次,只需要修改循环条件,不需要复制 100 份代码。这正是循环的价值:把重复次数交给条件控制。
循环边界与死循环
当输出次数或范围不符合预期时,先检查循环边界;如果程序一直运行,再检查是否进入死循环。
循环边界
问题:为什么下面两种写法都执行 5 次,但输出范围不同?
下面两种写法都会执行 5 次:
count = 1
while count <= 5:
print(count)
count += 1count = 0
while count < 5:
print(count)
count += 1两段代码的执行次数相同,但输出范围不同:第一段输出 1 到 5,第二段输出 0 到 4。
分析循环次数时,不要只看 < 或 <=,还要同时确认循环变量的起始值。
死循环排查
问题:如果程序一直输出相同内容,循环到底卡在哪里?
如果循环条件一直成立,程序就会反复执行,无法正常结束,这种情况叫作死循环。
count = 1
while count <= 5:
print(f"完成第 {count} 次练习")
# count += 1 # 忘记更新变量,count 会一直等于 1运行这段代码后,条件 count <= 5 始终成立,因此程序会不断输出相同内容。遇到类似问题时,可以先停止程序,再依次检查:
- 循环变量是否设置了合理的初始值
- 循环条件是否有机会变为
False - 循环变量是否在循环体中正确更新
- 更新方向是否与结束条件一致
例如,条件要求 count 逐渐超过 5,却写成 count -= 1,同样无法结束循环。
累加计算
如果每轮不只是输出,还要把结果逐步汇总,循环变量和累计变量应该怎样分工?
需求:计算 1 到 100 的和。
循环不仅能重复输出,还能把每轮计算的结果累积起来。
number = 1
total = 0
while number <= 100:
total += number
number += 1
print(total)运行结果:
5050这里有两个分工不同的变量:
number控制当前加到哪个数字total保存已经累加得到的结果
每轮循环先把 number 加入 total,再让 number 增加 1。当 number 变成 101 时,条件不再成立,循环结束。
嵌套 while 循环
如果任务同时包含“输出多行”和“每行输出多个内容”两层重复,怎样避免把每一行都手写?
一个 while 循环内部还可以再写一个 while,这种结构叫作嵌套循环。通常由外层循环控制行,内层循环控制每一行中的内容。
案例:星号三角形
需求:连续输出 5 行星号,每行的星号数量与行号相同。
*
**
***
****
*****利用字符串的 * 运算,一个循环就可以完成:
row = 1
while row <= 5:
print("*" * row)
row += 1这里的 row 既表示当前行号,也决定这一行需要输出多少颗星。
案例:逐颗打印星号(变式)
如果不使用字符串的 * 运算,就要再添加一个循环,逐颗输出每一行的星号:
row = 1
while row <= 5:
# 每进入新的一行,列数都要重新从 1 开始
col = 1
# 当前是第几行,就打印几颗星
while col <= row:
print("*", end="")
col += 1
# 当前行打印完成后换行
print()
row += 1这段代码中,两个循环各有自己的任务:
- 外层循环使用
row控制一共打印多少行 - 内层循环使用
col控制当前行打印多少颗星
col = 1 必须写在外层循环里面。每开始新的一行,都要重新计算这一行的列数。
从手动输出到嵌套循环
下面三段代码的输出结果相同。对照它们,可以看到重复代码是怎样逐步整理成嵌套循环的。
print("*", end="")
print()
print("*", end="")
print("*", end="")
print()
print("*", end="")
print("*", end="")
print("*", end="")
print()
print("*", end="")
print("*", end="")
print("*", end="")
print("*", end="")
print()
print("*", end="")
print("*", end="")
print("*", end="")
print("*", end="")
print("*", end="")
print()row = 1
col = 1
while col <= row:
print("*", end="")
col += 1
print()
row = 2
col = 1
while col <= row:
print("*", end="")
col += 1
print()
row = 3
col = 1
while col <= row:
print("*", end="")
col += 1
print()
row = 4
col = 1
while col <= row:
print("*", end="")
col += 1
print()
row = 5
col = 1
while col <= row:
print("*", end="")
col += 1
print()row = 1
while row <= 5:
col = 1
while col <= row:
print("*", end="")
col += 1
print()
row += 1:::
案例:九九乘法表
现在把“外层控制行、内层控制内容”的方法迁移到一个完整的输出任务。
需求:输出九九乘法表,并让第 n 行只显示前 n 个乘法表达式。
九九乘法表和星号三角形具有相同的结构:外层控制行,内层控制每行需要输出的内容。
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实现时,可以沿用星号三角形的思路:
- 外层循环控制第几行
- 内层循环控制当前行有多少列
- 把每颗星替换成对应的乘法表达式
# 从第 1 行开始
row = 1
# 乘法表一共有 9 行
while row <= 9:
# 每一行都从第 1 列开始
col = 1
# 当前是第几行,就打印几个乘法表达式
while col <= row:
print(f"{col} × {row} = {col * row}", end="\t")
col += 1
# 当前行打印完成后换行
print()
row += 1观察内层条件 col <= row:第 3 行最多打印到 3 × 3,第 9 行最多打印到 9 × 9。因此,输出内容会自然形成三角形。
小结
本章沿着四个问题推进:
- 如何让一段代码按条件重复执行?使用
while - 次数不对或程序停不下来时,应该检查什么?检查边界和变量更新
- 每轮结果如何逐步汇总?区分循环变量和累计变量
- 多行多列的任务如何拆分?用嵌套循环让外层控制行、内层处理每行内容
遇到循环结果不符合预期时,可以记录每轮循环变量的值,沿着“判断条件 → 执行循环体 → 更新变量”的顺序逐步排查。