今天你 AI 赋能了吗?打开浏览器,在地址栏输入 xuefulu.ai ,按下 Enter 即可访问学府路1号!
2026年10月14日 星期三 10:40:14
常用网址: | | 学府路1号 https://xuefulu.ai | 下载 Python https://xuefulu.ai/Python.html | 下载 TRAE https://xuefulu.ai/Trae.html

一、为什么需要循环

先做个小实验。要在屏幕上打印 5 遍「我要学 Python」,最直接的办法是抄 5 行:

Python
print('我要学 Python')
print('我要学 Python')
print('我要学 Python')
print('我要学 Python')
print('我要学 Python')

能跑,但很笨。那要打印 100 遍呢?抄 100 行吗?

这时候就该请出循环了:把「要重复做的事」只写一遍,再告诉 Python 重复多少次。

Python
for i in range(5):
    print('我要学 Python')

5 行变 2 行。想改成 100 遍,只要把 5 改成 100。这就是循环最大的价值:重复的事只写一遍。

循环不只是「少打几个字」。真实的数据来自文件、网络或用户输入,条数事先根本不知道——比如「把所有同学的分数加起来」,你没法提前抄好代码,只能靠循环。

循环的三要素

不管哪种循环,脑子里都要有这三样东西:

要素含义例子(从 1 数到 5)
① 起点从哪儿开始从 1 开始
② 条件什么时候还继续只要还没超过 5
③ 变化每转一圈往终点靠近一点每次加 1

三要素里最容易漏掉的是 ③ 变化。忘了它,条件永远成立,程序就会一直转下去——这叫死循环,后面第十二节专门讲怎么处理。

两种循环,两种长相

写法一句话理解适合什么场景典型例子
for把一串东西挨个过一遍事先知道要遍历什么遍历列表、字符串、range()
while条件成立就一直转靠条件决定停不停猜数字、输入到某个字符才退出

下面先讲 for,再讲 while,最后讲循环里两个「紧急刹车」——break 和 continue。

课程思政|科技自立自强 · 重复交给机器,判断留给人

打印 100 遍不用抄 100 行,把重复的部分写一遍、交给 for 转就行。机器最擅长的,就是把同一件事做上一万遍也不喊累,而人该把力气花在「要不要重复、怎么重复」这些判断上。想想工业软件、自动化产线为什么是硬骨头——谁能让机器替人扛下重复,谁就真正握住了主动权。学循环,也是在学怎么把力气用在刀刃上。

二、for 循环:把一串东西挨个过一遍

for 循环的长相,就是把「一串东西」交给它,它一个一个拿出来用:

Python
# 示意:把「一串东西」换成真实的列表、字符串或 range(...)
for 变量 in 一串东西:
    要重复做的事(记得缩进)

这是长相,不是能直接跑的代码——一串东西 还没定义呢。看几个真能跑的:

Python
for char in 'Hello':
    print(char)

输出:

输出
H
e
l
l
o

把 'Hello' 看成 5 个字符排成的队,for 就是从头到尾依次取出一个交给 char,取完了就结束。

换成列表也一样。列表就是前面学过的、用方括号装一串东西:

Python
hotpot = ['毛肚', '肥牛', '虾滑', '鸭肠']
for dish in hotpot:
    print('下锅:', dish)

输出:

输出
下锅: 毛肚
下锅: 肥牛
下锅: 虾滑
下锅: 鸭肠

元组(用圆括号装一串东西)也能遍历:

Python
for n in (1, 2, 3):
    print(n)

输出 1、2、3。

每一圈发生了什么

上面那个火锅配菜的例子,一圈一圈拆开是这样的:

第几圈dish 的值打印出来的话
第 1 圈毛肚下锅: 毛肚
第 2 圈肥牛下锅: 肥牛
第 3 圈虾滑下锅: 虾滑
第 4 圈鸭肠下锅: 鸭肠
没有第 5 圈——列表取完了,循环结束

循环变量起什么名字

for 后面那个变量叫循环变量,每转一圈它就换成下一个元素。名字自己起,但建议起得能看懂:

写法评价
for fruit in fruits:很好,一看就知道装的是水果
for s in scores:很好,s 是分数的意思
for i in range(5):可以,约定俗成 i 表示序号/计数
for x in fruits:能用,但 x 看不出是什么

循环结束后,变量还在

这一点新手常常想不到:循环变量不是只在循环里面有效,循环结束后它仍然是最后一个值。

Python
for i in range(3):
    pass
print('循环结束后 i =', i)

输出 循环结束后 i = 2。因为 range(3) 给出 0、1、2,最后一圈 i 是 2。

遍历字典时,for 默认交出的是键。d = {'姓名': '小明', '年龄': 18},写 for k in d: 会依次得到 '姓名'、'年龄',还可以用 d[k] 取出对应的值。

三、range():批量造出数字

上一个例子里的 range(5) 是造一串数字用的。程序里要「重复 10 次」「从 1 加到 100」都靠它。

它本身不是列表,用 list() 包一下才能看见里面是什么:

Python
print(list(range(5)))

输出 [0, 1, 2, 3, 4]。注意:从 0 开始,到 5 结束但不包含 5。

四种常见写法

写法产出的数字什么时候用
range(5)0, 1, 2, 3, 4重复 5 次,或从 0 开始数
range(1, 6)1, 2, 3, 4, 5从 1 数到 5
range(1, 11, 2)1, 3, 5, 7, 9隔一个取一个
range(10, 0, -1)10, 9, 8 … 1倒着数

挨个跑一遍看结果:

Python
print(list(range(5)))
print(list(range(1, 6)))
print(list(range(1, 11, 2)))
print(list(range(10, 0, -1)))

输出:

输出
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 3, 5, 7, 9]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

三条必须记住的规则

  1. 终点不包含。想数到 5,得写 range(1, 6);想数到 100,得写 range(1, 101)。这是新手出错最多的地方。
  2. 只写一个数字时,从 0 开始。range(5) 就是 range(0, 5)。
  3. 第三个数字是「步长」,默认 1。写 -1 就能倒着数。
下面这种写法不会报错,但一次都不会循环——因为起点 5 已经超过终点 1,而步长默认是 +1,越走越远:
for i in range(5, 1):
屏幕上什么也不显示,程序直接跳到循环后面。倒着数必须写 range(5, 0, -1)。
想确认 range 到底给出几个数,用 len() 数一数即可:len(range(1, 101)) 的结果是 100。

四、循环的四个基本功

循环用得最多的四件事,记成四个「模板」就行。以后遇到类似题目,直接往里套。

基本功 1:累加(把一串数加起来)

套路是:先在循环外面准备一个「零钱罐」变量,循环里往里扔。

Python
total = 0
for i in range(1, 101):
    total += i
print('1~100 的和是', total)

输出 1~100 的和是 5050。

两条铁律:① 零钱罐一定要在循环之前设成 0;② total += i 要写在循环体里面(缩进四格)。写在循环外面就只加最后一次。

基本功 2:计数(数一数有多少个)

和累加几乎一样,只不过每次加的是 1。比如数一句话里出现了几个「吃」字:

Python
text = '我想吃火锅想吃烧烤想吃炸鸡'
count = 0
for ch in text:
    if ch == '吃':
        count += 1
print('「吃」字出现了', count, '次')

输出 「吃」字出现了 3 次。

基本功 3:找最大(最值)

套路是:先假定第一个就是最大的,然后拿后面的一个个来挑战。

Python
scores = [88, 92, 75, 96, 81]
best = scores[0]
for s in scores:
    if s > best:
        best = s
print('最高分是', best)

输出 最高分是 96。

千万别把 best = scores[0] 写成 best = 0。如果所有分数都是负数,0 永远「最大」,结果就错了。先拿第一个当擂主最保险。

基本功 4:求平均

先用累加求出总和,再除以个数(个数用 len() 数)。

Python
scores = [88, 92, 75, 96, 81]
total = 0
for s in scores:
    total += s
print('平均分是', total / len(scores))

输出 平均分是 86.4。

Python 其实有现成的 sum() 和 max(),sum(scores) 直接得到 432、max(scores) 直接得到 96,效果和上面一样。但循环版本一定要会写——以后要统计的不是「加起来」而是更复杂的规则时,现成函数帮不上忙。

课程思政|工匠精神与严谨求实 · 零钱罐要先归零

累加前要把「零钱罐」变量先设成 0,而且 total += i 必须写在循环体里面——这两步错一步,结果就全错。真正的功夫,往往就藏在这些看起来最简单的地方。找最大最小时也一样,先假定第一个,再让后面一个个来挑战,别一上手就想当然。把每个基本功练到不用想就对,复杂的数据处理才站得稳。

五、while 循环:条件成立就一直转

for 是「有一串东西要过一遍」,while 是「条件成立就一直转」。三要素在写法上看得特别清楚:

Python
# 示意:三要素缺一不可
变量 = 起点值              # ① 起点
while 条件:                # ② 条件成立就继续转
    要重复做的事
    变量 = 变量 + 1         # ③ 变化:往终点靠近

把「从 1 加到 100」用 while 写一遍:

Python
total = 0
i = 1
while i <= 100:
    total += i
    i += 1
print('1~100 的和是', total)

输出 1~100 的和是 5050,和 for 版结果一模一样。

倒计时

Python
i = 3
while i > 0:
    print(i)
    i -= 1
print('发射!')

输出 3、2、1、发射!。

一直收到 0 才停(次数事先不知道)

这是 while 真正的用武之地——要转多少圈,得看用户输入几次:

Python
total = 0
num = int(input('输入一个数字(输入 0 结束):'))
while num != 0:
    total += num
    num = int(input('输入一个数字(输入 0 结束):'))
print('所有输入数字的总和是:', total)

运行起来是这样(输入 5、8、0):

输出
输入一个数字(输入 0 结束):5
输入一个数字(输入 0 结束):8
输入一个数字(输入 0 结束):0
所有输入数字的总和是: 13
注意 input() 读进来的都是字符串,要和数字比较或做加法,必须先 int() 转换,否则会报 TypeError: '>' not supported between instances of 'str' and 'int'。

猜数字游戏

循环次数事先完全不知道,转到猜对为止:

Python
import random

random.seed(42)              # 固定随机结果,方便对照,写程序时可以不写
target = random.randint(1, 10)
guess = None                 # 先随便给一个和答案不同的值
while guess != target:
    guess = int(input('猜一个 1~10 之间的数字:'))
    if guess < target:
        print('猜小了!')
    elif guess > target:
        print('猜大了!')
print('恭喜,猜中了!')

猜 5、1、2 时是这样(seed(42) 之后答案固定是 2):

输出
猜一个 1~10 之间的数字:5
猜大了!
猜一个 1~10 之间的数字:1
猜小了!
猜一个 1~10 之间的数字:2
恭喜,猜中了!
guess = None 这一句别省。None 表示「什么都没有」,先用它占个位置,保证第一次 guess != target 一定成立,循环能顺利进得去。

while True:故意不写条件

while True 意思是「永远转下去」,退出全靠循环里的 break(下一节讲)。 这是写菜单、命令行程序最常用的长相:

Python
i = 1
while True:
    print(i)
    i += 1
    if i > 3:
        break

输出 1、2、3。循环里必须有一条能 break 出去的路, 否则就是死循环,只能按 Ctrl + C 强行停下。

六、for 还是 while

两个都能实现「从 1 加到 100」,那到底用哪个?看你的依据是什么。

forwhile
依据我有一串东西要挨个过我有个条件,成立就继续
圈数由那串东西的长度决定由条件什么时候不成立决定
圈数事先知道吗基本知道常常不知道
最怕什么写错 range 的终点忘了改变量 → 死循环
典型场景遍历列表/字符串、重复 N 次、累加 1~N猜数字、输入到某字符退出、菜单循环

同一道题两种写法对照(1~100 累加):

Python
# for 版:我清楚要过一遍 1~100 这些数字
total = 0
for i in range(1, 101):
    total += i
print(total)
Python
# while 版:我关心「还没到 100 就继续」
total = 0
i = 1
while i <= 100:
    total += i
    i += 1
print(total)

两句都输出 5050。

选不出来的口诀:能数出「一共几个」就用 for,只能说出「满足什么条件」就用 while。遍历列表、字符串一律用 for,别去写 for i in range(len(x)) 绕一圈。

七、break:提前收工

break 的意思是「不转了,立刻收工」——跳出整个循环,接着执行循环后面的代码。

Python
# 示意
for 变量 in 一串东西:
    if 某个条件:
        break          # 整个循环到此结束
    其他要重复的事

在 for 里用:找到 5 就收工,所以只打印到 4。

Python
for i in range(1, 11):
    if i == 5:
        break
    print(i)

输出:

输出
1
2
3
4

在 while 里用:数到 7 就收工。

Python
num = 1
while num <= 10:
    if num == 7:
        break
    print(num)
    num += 1

输出 1 到 6。

最常见的用法:找到第一个就停

想找 1~99 里第一个能被 7 整除的数,找到了就没必要往下找了:

Python
for i in range(1, 100):
    if i % 7 == 0:
        print('第一个能被 7 整除的数是', i)
        break

输出 第一个能被 7 整除的数是 7。

输入类程序:用 break 当出口

Python
while True:
    cmd = input('请输入命令(q 退出):')
    if cmd == 'q':
        break
    print('你输入了', cmd)
print('程序结束')

运行效果(先输入 3、再输入 q):

输出
请输入命令(q 退出):3
你输入了 3
请输入命令(q 退出):q
程序结束
break 只管最近的那一层循环。如果有两层嵌套,内层 break 之后外层照样继续转——想一次跳出两层,得在外层再加一个判断(或者用一个「标志变量」)。

八、continue:跳过这一次

continue 是「这一圈不算,直接开始下一圈」。它不结束循环,只是跳过本圈剩下的代码。

Python
# 示意
for 变量 in 一串东西:
    if 某个条件:
        continue       # 本圈剩下的代码不执行了,直接下一圈
    其他要重复的事

只打印奇数:遇到偶数就跳过本次的 print(i)。

Python
for i in range(1, 11):
    if i % 2 == 0:
        continue
    print(i)

输出:

输出
1
3
5
7
9

在 while 里跳过 3 的倍数:

Python
num = 0
while num < 10:
    num += 1
    if num % 3 == 0:
        continue
    print(num)

输出 1、2、4、5、7、8、10,3、6、9 都被跳过了。

while 里用 continue 有个大坑:如果「改变量」那一句正好排在 continue 后面,它永远轮不到执行,条件永远成立——变成死循环。
所以 num += 1 建议写在 continue 前面(像上面那样),或者干脆改用 for。

break 与 continue 对照

breakcontinue
一句话整个循环不要了只要跳过这一圈
本圈剩下的代码不执行不执行
下一圈不会再有了照常继续
循环后面的代码接着执行等循环正常结束才执行
经典场景找到目标就收工过滤掉不需要的数据

同一组气温里跳过零下的:

Python
temps = [3, -1, 5, -2, 8]
for t in temps:
    if t < 0:
        continue
    print(t)

输出 3、5、8。

九、pass:什么都不做的占位符

pass 是 Python 里唯一一个「什么都不做」的语句。它不打印、不算数、不改任何变量——放在那里,纯粹就是占个位置。

为什么需要这么个「废话」?因为 Python 靠缩进划分代码块,冒号后面必须真的写上代码。有时候结构已经想好了,但某一路暂时没什么要做的,又不能空着,这时就用 pass 顶住。

示意
# 示意:位置先占住,等想好了再把 pass 换成真正要做的事
if 条件1:
    pass
else:
    其它分支要做的事,想好了写在这里

反过来,冒号后面真的什么都不写,Python 会立刻报错:

Python
if True:
print(1)
报错
IndentationError: expected an indented block after 'if' statement on line 1

原因:Python 没有花括号 {} 来圈住代码块,它用缩进。冒号后面缩进一级的那些行,就是「这个分支的内容」;一行都没有,Python 就不知道这个分支到底存不存在。pass 提供的正是「一行,但什么都不做」。

案例 1:先把结构搭起来

还没想好「及格了要干嘛」,就用 pass 先占着,程序照样能跑。

Python
score = 55
if score >= 60:
    pass                    # 及格的同学暂时不处理,先留个位置
else:
    print('成绩不合格,需要补考')
print('检查结束')            # 分支走完,程序继续往下

输出:

输出
成绩不合格,需要补考
检查结束

案例 2:循环里用 pass,什么都不会被跳过

Python
for i in range(1, 6):
    if i == 3:
        pass            # 第 3 圈先放着,什么都不做
    print('第', i, '圈')

输出:

输出
第 1 圈
第 2 圈
第 3 圈
第 4 圈
第 5 圈

第 3 圈照样打印出来了——pass 什么都没影响。

记住这条:pass 不会跳过任何东西。它只是「站在这儿什么也不干」——pass 后面的代码、以及这一圈剩下的代码,全都照常执行。

案例 3:pass 和 continue 到底差在哪

同一段需求写成两版,一眼就能看出区别:上面「第 2 圈也照样走完」,下面「第 2 圈就此打住」。

Python
for i in range(1, 4):
    if i == 2:
        pass
    print('第', i, '圈')

输出:

输出
第 1 圈
第 2 圈
第 3 圈
Python
for i in range(1, 4):
    if i == 2:
        continue
    print('第', i, '圈')

输出 第 1 圈、第 3 圈——第 2 圈的 print 被跳过了。

一句话总结:pass 是「这一圈也照样走完」,continue 是「这一圈就到此为止」。

pass / continue / break 三兄弟对照

passcontinuebreak
一句话什么都不做跳过这一圈整个循环不要了
本圈剩下的代码照常执行不执行不执行
下一圈照常继续照常继续不会再有了
循环后面的代码等循环正常结束等循环正常结束立刻接着执行
典型用途占位、留白过滤掉不要的数据找到目标就收工

案例 4:把不认识的情况先放过去

Python
while True:
    cmd = input('请输入命令:')
    if cmd == 'q':
        break
    elif cmd == 'show':
        print('显示数据')
    else:
        pass            # 其它命令暂时不处理,也不报错
print('结束')

运行效果(依次输入 show、hello、q):

输出
请输入命令:show
显示数据
请输入命令:hello
请输入命令:q
结束
别让 pass 变成偷懒的借口。它只适合「暂时」占位——想好之后一定要回头把 pass 换成真正的代码。如果这个分支本来就什么都不用做,更干净的做法是直接把这一路删掉,而不是留一个空的 pass。
两个易错写法:pass 全是小写,写成 Pass 会报 NameError: name 'Pass' is not defined;写成 pass() 会报 SyntaxError——它是语句,不是函数,后面不能带括号。
另外,以后学函数时会再见到它:def 定义了一个暂时不写内容的函数,函数体里同样要用 pass 顶住。

十、循环套循环(嵌套)

循环体内还可以再写一个循环。外面的管「第几行」,里面的管「这一行有几个」——这是嵌套循环最好用的思路。

Python
for i in range(1, 6):
    for j in range(i):
        print('*', end='')     # end='' 表示不换行
    print()                    # 一行结束后换行

输出:

输出
*
**
***
****
*****
print() 默认会换行,print('*', end='') 把结尾改成空字符串就不换行了;一行拼完再用一句空的 print() 换行。这是打图形、打表格的标准套路。

九九乘法表(前四行)

Python
for i in range(1, 5):
    for j in range(1, i + 1):
        print(f'{j}x{i}={i * j}', end=' ')
    print()

输出:

输出
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16

把 range(1, 5) 改成 range(1, 10),就是完整的九九乘法表。第 i 行的诀窍在于内层写的是 range(1, i + 1)——行号越大,这一行的算式越多。

嵌套里的一圈一圈

外层 i内层 j 依次取到打印
111x1=1
21, 21x2=2 2x2=4
31, 2, 31x3=3 2x3=6 3x3=9
41, 2, 3, 41x4=4 2x4=8 3x4=12 4x4=16
嵌套里的 break 和 continue 只作用在它所在的那一层。下面这段里内层一遇到 j == 2 就 break,但外层照转,所以打印出 1 1、2 1、3 1:
for i in range(1, 4): / for j in range(1, 4): / if j == 2: break / print(i, j)

AI 助手小贴士|嵌套循环是循环的 boss 关,让 AI 把执行轨迹摆成表格看。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:用文字表格演示九九乘法表双重循环的执行顺序:外层 i=1 时内层 j 循环几次、各打印什么,最后一共打印多少行

课程思政|诚信与职业操守 · 表要一行行对齐

九九乘法表外层管第几行、内层管这一行有几句,行号越大算式越多,一格都不能错位。打表如此,做报表也一样——每一格背后都是一个真实的数。我们统计人往后要面对的是成绩单、财务报表、调查数据,行列一错、口径一乱,别人就会照着错误的结论去做决定。先把这张乘法表对齐,是诚实对待每一个数字的起点。

十一、十个能直接跑的小案例

下面十个例子都很短,建议每个都亲手敲一遍、跑一遍。

1. 1~100 全部加起来

Python
total = 0
for i in range(1, 101):
    total += i
print(f'1~100 的和是 {total}')

输出 1~100 的和是 5050。

2. 1~100 里所有偶数加起来

Python
total = 0
for i in range(1, 101):
    if i % 2 == 0:
        total += i
print(f'1~100 的偶数和是 {total}')

输出 1~100 的偶数和是 2550。

3. 数一数字符串里有几个指定字符

Python
text = '我想吃火锅想吃烧烤想吃炸鸡'
count = 0
for ch in text:
    if ch == '吃':
        count += 1
print(f'「吃」字出现了 {count} 次')

输出 「吃」字出现了 3 次。

4. 找出一组分数里的最高分

Python
scores = [88, 92, 75, 96, 81]
best = scores[0]
for s in scores:
    if s > best:
        best = s
print(f'最高分是 {best}')

输出 最高分是 96。

5. 求平均分

Python
scores = [88, 92, 75, 96, 81]
total = 0
for s in scores:
    total += s
average = total / len(scores)
print(f'共 {len(scores)} 人,平均分 {average}')

输出 共 5 人,平均分 86.4。

6. 统计及格和不及格的人数

Python
scores = [88, 55, 72, 40, 91]
passed = 0
failed = 0
for s in scores:
    if s >= 60:
        passed += 1
    else:
        failed += 1
print(f'及格 {passed} 人,不及格 {failed} 人')

输出 及格 3 人,不及格 2 人。两个计数器可以并排放,各数各的。

7. 求阶乘(5 的阶乘 = 1×2×3×4×5)

累加的零钱罐设成 0,累乘要设成 1:

Python
n = 5
result = 1
for i in range(1, n + 1):
    result *= i
print(f'{n} 的阶乘是 {result}')

输出 5 的阶乘是 120。

8. 打印斐波那契数列前 8 项

Python
a, b = 0, 1
for i in range(8):
    print(a, end=' ')
    a, b = b, a + b

输出 0 1 1 2 3 5 8 13。每一项都是前两项之和。

9. 找水仙花数(100~999 内)

水仙花数指「各位数字的立方和等于自己」,比如 153 = 1³ + 5³ + 3³:

Python
for n in range(100, 1000):
    a = n // 100            # 百位
    b = n // 10 % 10        # 十位
    c = n % 10              # 个位
    if a ** 3 + b ** 3 + c ** 3 == n:
        print(n, end=' ')

输出 153 370 371 407,一共 4 个。

10. 判断一个数是不是质数

质数只能被 1 和自己整除。只要在 2 到 n - 1 之间找到一个能整除它的数,就可以立刻下结论:

Python
n = 29
is_prime = True
for i in range(2, n):
    if n % i == 0:
        is_prime = False
        break
if is_prime:
    print(f'{n} 是质数')
else:
    print(f'{n} 不是质数')

输出 29 是质数。把 n 改成 35,输出 35 不是质数。

十二、最容易踩的六个坑

坑 1:死循环——程序卡住不动了

while 的条件永远成立,程序就会一直转。最常见的两个原因:

Python
# 原因一:循环里忘了改变量,i 永远是 1
i = 1
while i <= 3:
    print('永远在转')
Python
# 原因二:continue 跳过了改变量的那一句
i = 0
while i < 5:
    if i == 2:
        continue        # 一到 2 就回到开头,i 永远到不了 3
    print(i)
    i += 1
程序卡在死循环里时,在运行窗口按 Ctrl + C 可以强行停下,屏幕上会出现 KeyboardInterrupt。这不是你写错了语法,而是你主动按停的——看到它就是「死循环被中断了」。
预防办法:写 while 时先问自己一句「变量在哪一步变小/变大,最后一定会让条件不成立?」

坑 2:range 的终点不包含

想要的效果正确写法写成这样会怎样
数到 5range(1, 6)range(1, 5) 只到 4
数到 100range(1, 101)range(1, 100) 只到 99
数到 nrange(1, n + 1)range(1, n) 少了 n
口诀:想要几就写几加一。从 1 到 n 一律写 range(1, n + 1)。

坑 3:缩进决定谁在循环里

Python
for i in range(3):
    print('在循环里(打印 3 次)')
print('在循环外(只打印 1 次)')

第 2 行缩进四格,属于循环体;第 3 行顶格写,属于循环之后。挪动 4 个空格,执行次数完全不同。

缩进多少格不影响功能(四格、八格都行),只要同一层的缩进完全一致即可。但不要同一个文件里有的地方敲 Tab、有的地方敲空格——会报 TabError。Python 社区的习惯是统一用 4 个空格,IDLE 里敲 Tab 会自动转成 4 个空格。

坑 4:for 循环里改循环变量没用

下面这段你以为会打印 0 然后就跳到 10,实际上是 0、1、2:

Python
for i in range(3):
    print(i)
    i = 10          # 改了也没用,下一圈重新从 range 里取值

因为 for 每转一圈都会重新把序列里的下一个值赋给 i,你在循环体里的赋值会被冲掉。 "想控制进程请用 break 或 continue;while 里改变量才是有效的(那正是它的「变化」要素)。

坑 5:边遍历边删列表

Python
nums = [1, 2, 3, 4]
for n in nums:
    if n == 2:
        nums.remove(n)
print(nums)

结果是 [1, 3, 4]——2 是删掉了,但 3 被跳过了。删掉元素后,后面的元素会往前挪一位,循环的下标也跟着走,正好错过一个。

要「筛选」一份数据,别在遍历时删原列表。可以新建一个:keep = [],循环里满足条件就 keep.append(x),遍历完再 nums = keep。

坑 6:想遍历数字却忘了 range

Python
# 错误:5 是个数字,不是一串东西
for i in 5:
    print(i)

报 TypeError: 'int' object is not iterable。改成 for i in range(5): 就好了。 for 后面必须跟「一串东西」:列表、字符串、元组、range() 都可以,单个数字不行。

AI 助手小贴士|循环的 bug 千篇一律:死循环、差一错误。练「找 bug」眼力。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:出 3 道找 bug 题:每段循环代码里藏着一个死循环或差一错误,让我先找出来再对答案

十三、报错手册

下面这些报错都是真实运行出来的,照抄本机解释器的原文。看到眼熟的,直接对照处理。

照抄出来的报错

Python
for i in 5:
    print(i)
报错
TypeError: 'int' object is not iterable

原因:for 后面必须跟一串东西。改成 for i in range(5):。

Python
for i in range(1, 5.0):
    print(i)
报错
TypeError: 'float' object cannot be interpreted as an integer

原因:range() 只收整数。小数要先 int() 转换,或者改用别的方式生成小数序列。

Python
for i in range(3)
    print(i)
报错
SyntaxError: expected ':'

原因:for 那一行结尾漏了冒号。冒号、缩进是 for 语句的两个必备零件。

Python
for i in range(3):
print(i)
报错
IndentationError: expected an indented block after 'for' statement on line 1

原因:循环体没有缩进。缩进就是「告诉 Python 哪些代码属于循环」的符号,不能省。

Python
for i in range(3):
    print(i)
报错
SyntaxError: invalid character ':' (U+FF1A)

原因:用了中文全角冒号。输入法在中文状态下容易打出全角的标点,切换成英文再打。

Python
print('开始')
break
报错
SyntaxError: 'break' outside loop

原因:break 只能写在循环里面。没有循环,它不知道该结束谁。

Python
continue
报错
SyntaxError: 'continue' not properly in loop

原因:同上,continue 也必须待在循环体内。

Python
for i in range(3):
    print(total)
报错
NameError: name 'total' is not defined

原因:变量还没定义就用了。累加器的 total = 0 必须写在循环之前。

Python
for i in range(3):
    print('第' + i + '次')
报错
TypeError: can only concatenate str (not "int") to str

原因:字符串不能直接和数字相加。要么 str(i) 转换,要么直接用 f-string:print(f'第{i}次')。

Python
for i in rang(3):
    print(i)
报错
NameError: name 'rang' is not defined. Did you mean: 'range'?

原因:函数名拼错。较新的 Python 3 版本会直接猜出你想写的是 range,照它提示改就行。

Python
while true:
    print('hi')
报错
NameError: name 'true' is not defined. Did you mean: 'True'?

原因:Python 里的真值必须大写 True。写成 true、TRUE 都不认。

Python
n = input('输入一个数字:')
while n > 0:
    print(n)
    n = n - 1
报错
TypeError: '>' not supported between instances of 'str' and 'int'

原因:input() 读进来的永远是字符串,字符串和数字比不了大小。改成 n = int(input('输入一个数字:'))。

Python
n = 5
for i in range(len(n)):
    print(i)
报错
TypeError: object of type 'int' has no len()

原因:len() 只能量「一串东西」的长度,单个数字没有长度。想数到 5 就写 range(n)。

Python
score = 90
if score >= 60:
    Pass
报错
NameError: name 'Pass' is not defined

原因:Python 严格区分大小写,pass 必须全小写。写成了 Pass,Python 就把它当成一个从没定义过的变量名去取值,于是报 NameError。

不算报错,但会让你疑惑

现象真相
for i in range(5, 1): 什么都不打印,也不报错起点比终点大,而步长是正的,一个数都取不到。倒着数要写 range(5, 0, -1)。
程序卡住、光标一直闪,不报错也不结束死循环。按 Ctrl + C 中断,然后检查「改变量」那一步。或者检查 continue 是不是把改变量跳过了。
循环体缩进了 8 格,居然也能跑0、1、2 正常打印。缩进格数不影响功能,只要同一层一致;但混用 Tab 和空格会报 TabError。
循环结束后 i 居然还能用,值是 2循环变量不是局部变量,循环结束后它保留最后一圈的值。
加了 pass,可什么都没输出正常的。pass 就是「什么都不做」,它不打印、不计算、也不跳过任何代码;想跳过本圈要用 continue。
嵌套循环里写了 break,外层还在继续break 只结束最近的一层循环,想跳出两层要在外层再加判断。

AI 助手小贴士|双重循环的执行顺序靠脑子演容易乱。让 AI 一步一步列轨迹表,看两遍就开窍了。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:一步一步列出下面这段双重循环每轮的循环变量取值和打印结果,用表格呈现,最后总结外层和内层各跑了多少次:<粘贴代码>

十四、随堂自测(12 题)

点击选项即可判分,选错的题会立刻展开解析。做完可以看到正确率和错题清单,也可以重新答题。

已答 0 / 12 · 正确 0 —

1执行 for i in range(1, 5): 时,i 依次取到哪些值?

  • A. 1, 2, 3, 4, 5
  • B. 0, 1, 2, 3, 4
  • C. 1, 2, 3, 4
  • D. 1, 2, 3
答案:C。range 的终点不包含:起点 1 取得到,终点 5 取不到,所以是 1、2、3、4。想取到 5 必须写 range(1, 6)。

2while 循环写完后程序一直转、停不下来,最可能漏掉了三要素里的哪一个?

  • A. ① 起点(初始值)
  • B. ② 条件
  • C. ③ 变化(让变量靠近终点)
  • D. 循环体的缩进
答案:C。忘了改变量,条件永远成立,就成了死循环。写 while 时先问自己:变量在哪一步变大或变小,最后一定会让条件不成立?

3break 和 continue 的区别是什么?

  • A. break 结束整个循环,continue 只跳过本次、继续下一圈
  • B. break 跳过本次,continue 结束整个循环
  • C. 两个完全一样,只是写法不同
  • D. break 只能用在 for 里,continue 只能用在 while 里
答案:A。break 是「整个不干了」,continue 是「这一圈不算,接着下一圈」。两个在 for 和 while 里都能用。

4程序卡在死循环里一直在转,怎么把它停下来?

  • A. 按 F5 重启
  • B. 在运行窗口按 Ctrl + C
  • C. 不用管,它转一会儿会自己停下来
  • D. 把变量名改掉
答案:B。按 Ctrl + C 会强行中断,屏幕出现 KeyboardInterrupt。看到它说明循环已被你按停,接着去检查「改变量」那一步。

5想依次打印列表里的每个水果,下面哪种写法最合适?

  • A. for i in range(len(fruits)):
  • B. while fruits:
  • C. for fruit in fruits:
  • D. for fruit in range(fruits):
答案:C。遍历列表直接 for 变量 in 列表,简单又不容易错。A 绕了一圈还容易越界;D 会报错,因为 range() 不收列表。

6执行下面这段后 i 的值是多少?
for i in range(3):
pass

  • A. 0
  • B. 2
  • C. 3
  • D. 报错,循环变量在循环外不能用
答案:B。range(3) 给出 0、1、2,最后一圈 i 是 2。循环变量在循环结束后仍然保留最后一圈的值,可以直接用。

7写累加(把一串数加起来)时,循环开始前应该先把总和变量设成什么?

  • A. 0
  • B. 1
  • C. 第一个元素的值
  • D. 不用设,直接加
答案:A。累加设 0,累乘才设 1。而且 total = 0 必须写在循环之前,写在循环里每圈都会被清零。

8嵌套循环中,内层执行了 break 会发生什么?

  • A. 两层循环都结束
  • B. 只有外层结束
  • C. 程序直接报错
  • D. 内层结束,外层继续转下一圈
答案:D。break 只管最近的一层——内层停下,外层照常继续转。想一次跳出两层,得在外层再加一个判断(或者用标志变量)。

9打印三角形图形时,print('*', end='') 里的 end='' 起什么作用?

  • A. 让这一行不换行,接着在同一行继续打印
  • B. 把星号换成空字符串
  • C. 让循环提前结束
  • D. 给星号之间加空格
答案:A。print() 默认结尾换行,把结尾换成空字符串就留在同一行继续打,一行拼完再用一句空的 print() 换行。

10想「重复 10 次」却根本用不到那个序号,循环变量怎么写最合适?

  • A. for i in range(10):
  • B. for x in range(10):
  • C. for _ in range(10):
  • D. for range(10):
答案:C。下划线 _ 是约定俗成的「这个值我不要」,写出来别人一看就知道它不是重点。D 语法不对,少了一个变量名。

11关于 pass,下面说法正确的是?

  • A. pass 什么都不做,它后面的代码照样执行
  • B. pass 会跳过这一圈剩下的代码
  • C. pass 会结束整个循环
  • D. pass 和 continue 完全一样,只是写法不同
答案:A。pass 是空语句,只占位、不做任何事,后面的代码和这一圈剩下的代码都会照常执行。跳过本圈是 continue,结束整个循环是 break。

12写 for i in range(3): 之后直接换行,循环体一行都没写,会报什么错?

  • A. SyntaxError: expected ':'
  • B. NameError: name 'i' is not defined
  • C. 不报错,循环空转 3 次
  • D. IndentationError: expected an indented block after 'for' statement on line 1
答案:D。Python 用缩进划分代码块,循环体一行都没有就会报这个错。想先占位、以后再补内容,写一行 pass 即可。