第9章-循环控制


第9章 循环控制

让你打印 1 到 100,你会怎么写?如果老老实实写 100 行 print,那确实能跑,但谁写谁崩溃。程序存在的意义之一,就是代替人做重复的事。循环(loop)就是让程序自己重复干活:你说清楚"重复几遍、每次干什么",它一口气干完。像复读机,你设好次数,它就一遍遍念。

Python 给你两件工具:for(适合"数得清次数"的重复,比如 1 到 100)和 while(适合"做到某条件就不做了"的重复,比如"猜对了才停")。再配上 break(刹车:提前停)和 continue(跳车:跳过这一次继续)。学完循环,你就真正拥有"指挥程序干活"的权力了——明天猜数字和计算器全靠它。

for + range:数得清的重复

for 循环就是"把一件事重复做 N 遍"。最常用的搭档是 range(范围),它负责"产生一串数"。

for i in range(5):     # i 依次取 0, 1, 2, 3, 4
    print(i)

翻译成人话:让 i 依次把 range 里的数各拿一遍,每拿一个,就执行一次缩进的代码。i 是循环变量(名字随便起,i 是惯例),每轮循环它会自动变成下一个数。

range 有 3 种写法,都要背下来:

写法 生成什么 大白话
range(5) 0, 1, 2, 3, 4 从 0 开始,共 5 个数(含头不含尾
range(1, 6) 1, 2, 3, 4, 5 从 1 到 5
range(2, 101, 2) 2, 4, 6, ..., 100 从 2 开始,每次加 2,到 100 为止(第三个数是步长)

核心口诀:range 含头不含尾——range(1, 6) 只到 5,不到 6。想打印 1~100 要写 range(1, 101)

# 写法一:一个参数,从 0 开始
for i in range(5):        # 0 1 2 3 4
    print(i)

# 写法二:两个参数,含头不含尾
for i in range(1, 6):     # 1 2 3 4 5
    print(f"第{i}次循环")

# 写法三:三个参数,第三个是步长(每次加几)
for i in range(2, 101, 2):    # 2 4 6 ... 100(全是偶数)
    print(i)

# 步长也可以是负数:从大往小数
for i in range(10, 0, -1):    # 10 9 8 ... 1
    print(i)

# 循环次数 = 元素的个数
print("循环结束")

三个易错点:

  • 含头不含尾是最常错点:想打印 1~5 写 range(1, 5) 只会打 1,2,3,4。第二个数不包含,要 range(1, 6)
  • 循环变量每轮会被覆盖for i in range(3) 里 i 依次是 0、1、2,循环结束后 i 留在最后一个值 2。循环内不要手动改 i,循环自己会管理它,你改了容易乱。
  • 冒号和缩进:和 if 一样,冒号结尾、缩进 4 空格,缩进的代码才是"每次都要干的事"。

for 遍历列表:挨个点名

列表(list)是 Python 装多个东西的"带格子的收纳盒",用方括号 [] 表示:["苹果", "香蕉", "橙子"]for挨个取出列表里的每个元素处理一遍——就像点名册,老师挨个点名。

for 东西 in 列表:
    对"东西"做点什么

注意,这里循环变量取的是元素本身,不是下标数字。列表(以及更多数据结构)第 3 周会系统学,今天先用 for 和它打个照面。

fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
    print(f"今天吃 {fruit}")

# 输出:
# 今天吃 苹果
# 今天吃 香蕉
# 今天吃 橙子

# 对每个元素做运算也 OK
scores = [88, 92, 76]
total = 0
for s in scores:
    total = total + s          # 把每个分数累加进 total
print(f"总分:{total}")        # 总分:256

# 字符串也能遍历(逐个字符)
for ch in "Python":
    print(ch)                  # 依次输出 P y t h o n

三个点:

  • 循环变量是元素不是下标:for fruit in fruits 里 fruit 是"苹果"、"香蕉",不是 0、1、2。想要下标用 range(len(fruits))(今天先了解,第3周细学)。
  • 循环里累加要提前造"计数器":total = 0 必须先定义在循环外面,循环里 total = total + s 才能累加。把 total = 0 写进循环里,每轮都被清零,累加无效——这是新手高频错误。
  • 列表元素顺序就是遍历顺序:从上到下挨个来,不会乱序。

while:做到满意为止

while(当)循环 = "只要条件成立,就一直重复做"。它和 for 的分工:

  • for数得清次数的重复(循环 5 次、遍历 3 个元素)。
  • while说不清次数,看条件的重复("猜到答对为止"、"分数够 90 为止")。
while 条件成立:
    干这件事
    改条件 ← 别忘了!

最关键的坑:while 的条件必须"会变化",否则条件永远成立,程序会死循环。所以循环体里通常要有一行更新条件的代码(最常见的就是计数器 count = count + 1)。

# 计数器版:从 0 数到 2
count = 0                    # ① 造计数器
while count < 3:             # ② 看条件
    print(f"第 {count + 1} 次")
    count = count + 1        # ③ 改条件,否则死循环!

# 输出:
# 第 1 次
# 第 2 次
# 第 3 次

# 条件式:用户输入正确才停(明天猜数字的核心套路)
password = ""
while password != "888888":          # 密码不对就一直问
    password = input("请输入密码:")
print("密码正确,欢迎!")

# 用 while 做 1 到 100 求和(对比 for 的写法)
total = 0
i = 1
while i <= 100:
    total = total + i
    i = i + 1
print(total)        # 5050

while 的要点:

  • 三步不能少:造计数器 → 看条件 → 改条件。忘写 count = count + 1 或写错位置,条件永不改变,直接死循环。
  • while True: 是"永真"写法:条件直接写 True,等于"永远循环",必须配合 break 才能出来(下面讲,明天猜数字就用它)。
  • 循环体缩进:和 if 一样,冒号 + 缩进。条件不成立的那一刻,循环整体跳过,直接执行后面的代码。

break 和 continue:刹车与跳车

循环进行到一半,有时想提前退出,有时想跳过这一次。两个关键词:

  • break(刹车/退出):立刻结束整个循环,后面的循环次数都不做了,直接跳到循环后面的代码。
  • continue(跳车/继续):跳过这一次,不执行 continue 后面的代码,直接开始下一轮循环。

一句话区分:break 是"我不干了,全走人";continue 是"这次我不参与,下一轮见"

# break:到 5 就整个停
for i in range(10):
    if i == 5:
        break          # 循环直接结束
    print(i)           # 打印 0 1 2 3 4

# continue:跳过偶数,只打印奇数
for i in range(10):
    if i % 2 == 0:
        continue       # 偶数直接跳过本次,不打印
    print(i)           # 打印 1 3 5 7 9

# while 里用 break:输入 0 退出
while True:
    num = int(input("输入一个数(输入 0 退出):"))
    if num == 0:
        print("退出程序")
        break
    print(f"你输入了 {num}")

三个注意点:

  • break 只跳出"最近的一层"循环:嵌套循环里,内层 break 只结束内层,外层继续跑(嵌套循环下面讲)。
  • continue 后面的代码不执行:continue 要放对位置,它后面的同层代码这次循环都跳过。写完 continue 还指望后面的 print 执行,是常见逻辑错。
  • break / continue 只在循环里用:写在循环外面会报 SyntaxError: 'break' outside loop

死循环与自救

死循环(infinite loop)就是程序永远循环不结束,因为条件永远为 True。常见原因:

  1. while True: 忘了配 break
  2. 忘了更新 while 条件(计数器没加)
  3. 条件写反了
# 这是死循环!运行会卡住,请用 Ctrl + C 停止
count = 0
while count < 3:
    print("停不下来啦")
    # 忘了写 count = count + 1,条件永远成立

死循环不可怕,会自救就行

  • 症状:程序运行后不结束、光标一直闪、终端没反应——大概率死循环了。
  • 自救方法:终端窗口按 Ctrl + C(VSCode 的终端里也是)。按完能看到 KeyboardInterrupt 报错,这是"被你打断了"的正常信息,不是你的代码"更错了"。
  • 防死循环自查:每个 while 都检查两件事——① 条件涉及的变量在循环体里有没有被修改;② while True 有没有 break 路径能走到。写代码时养成习惯:凡是 while,先问自己"这个条件会不会变?退得出来吗?"

嵌套循环(进阶):循环套循环

循环里面再写循环,叫嵌套循环(nested loop)。运行顺序像钟表:分钟走一圈,小时才走一格——外层循环每执行一次,内层循环要完整跑完一遍。配合 range,就能打印"表格"。

# 先用个小例子理解"外层一次,内层一圈"
for i in range(1, 4):          # 外层:3 行
    for j in range(1, 4):      # 内层:每行 3 个
        print(f"({i},{j})", end=" ")   # end=" " 让它们排成一行
    print()                    # 一行打完,换行
# 输出:
# (1,1) (1,2) (1,3)
# (2,1) (2,2) (2,3)
# (3,1) (3,2) (3,3)

# 九九乘法表
for i in range(1, 10):              # 外层控制行:1 到 9
    for j in range(1, i + 1):       # 内层控制列:每行到 i 为止
        print(f"{j}x{i}={i*j}", end="  ")
    print()                         # 每行打完换行
# 输出(第一行):
# 1x1=1
# (第二行)1x2=2  2x2=4
# ...一直到最后一行

经典案例九九乘法表:它是一张 9 行 9 列的表格,外层循环管行(i),内层循环管列(j)。内层循环的范围还跟着外层走:第 i 行只打印 i 列(range(1, i + 1))。

三个注意点:

  • 内外层别搞反:外层跑得慢(只跑 9 次),内层跑得快(第 i 行跑 i 次)。想改"行数"改外层,想改"每行几个"改内层。
  • 内层范围随外层变化是精髓:range(1, i + 1) 让每行打印的列数随行号增长,这才形成三角形。
  • end=" " 负责"排成一行":默认 print 会换行,end=" " 把结尾改成两个空格;每行结束再用空 print() 换行。end 拼错成 " "(一个空格)只是排版略变,不影响对错。

随堂练习

  1. 练习一(偶数打印):打印 1 到 100 的所有偶数。 提示:两种写法都试一下——① range(2, 101, 2)(步长法);② range(1, 101) 里用 if i % 2 == 0 判断后打印。哪种更"笨"但更通用?

  2. 练习二(倒数):用 while 从 10 倒数到 1,每行打印一个数。 提示:计数器从 10 开始,条件是 count > 0,每轮 count = count - 1(注意是减 1,不是加 1,别忘了改条件)。

  3. 练习三(求和):用 forwhile 各写一遍:计算 1 加到 100,输出 5050。 提示:累加器 total = 0 放循环外,循环里 total = total + i。写完对照 for 版和 while 版,看哪个更好读。

  4. 练习四(密码机)while 循环实现:提示用户输密码,密码是 "1234" 才放行,错了继续问,并提示"密码错误,重试"。 提示:while password != "1234": 循环体内只有 input。输入对了,条件不成立,循环自动退出——这就是"条件式退出",不需要 break。

  5. 练习五(进阶:九九乘法表):打印完整的九九乘法表。 提示:参考上面嵌套循环的代码。先跑通,再试着改:把顺序反过来(先打印大数)看看效果;或者统计一下一共打印了多少个算式(count 计数器,答案 45)。

  6. 练习六(进阶:逢 7 跳过):用 for i in range(1, 101) 打印 1~100,但遇到含 7 的数(7、17、27...70~79 等)或 7 的倍数就跳过不打印,用 continue。 提示:判断条件 i % 7 == 0 or "7" in str(i)"7" in str(i) 意思是"数字转成字符串后里面有没有 7",这是字符串的 in 判断,先抄会用。

卡住了?让 AI 搭把手

场景:while 循环计数器忘改,变成死循环
提示词:我是 Python 零基础学生,我的 while 循环程序会一直运行停不下来。
下面是我的代码:[粘贴代码]。请指出为什么变成死循环,
用大白话解释 while 条件要怎么"变化",然后告诉我如何用 Ctrl + C 停止。
场景:九九乘法表不懂内层循环为什么跟着外层变
提示词:我是 Python 零基础学生,九九乘法表的嵌套循环看不懂。
请用"外层管行、内层管列"的思路,一步一步告诉我 range(1, i + 1) 是怎么工作的,
并用一个小的 3x3 例子演示。不要直接贴九九乘法表的完整代码。

常见报错速查

报错信息 / 问题 什么意思 怎么办
程序一直跑不停(终端没反应) 死循环:while 条件永远成立 Ctrl + C 停止;检查 while 条件涉及的变量有没有在循环里被更新
SyntaxError: 'break' outside loop break / continue 写在循环外面了 检查 break/continue 是否在 for 或 while 内部(缩进对了才算)
NameError: name 'total' is not defined 累加器没初始化就用 累加变量要在循环外面先赋值:total = 0
循环少打了一遍(如想打 1~5 只打了 1~4) range 含头不含尾写错了 想包含到 N,写 range(开始, N + 1)
只打印了最后一个数 print 缩进错了,写在循环外面了 检查 print 是否在循环体内(缩进对齐到循环体)

收个尾

今天的循环三件套——for(数得清次数的重复)、while(条件式重复)、break / continue(刹车与跳车)——配合前面的变量和判断,你已经能指挥程序干活了。核心口诀再念一遍:for 管次数,range 含头不含尾;while 三步走,忘改条件就死循环;卡住了按 Ctrl + C

明天是本周最后一课:综合练习,用本周全部知识做两个完整小程序——猜数字和计算器。猜数字要"猜不对就一直猜"(while),计算器要"算完一个再来一个"。今天把循环练熟,明天就能一口气做两个完整的小程序。