Python for循环练习题精讲:核心套路与避错指南
2026/9/23 3:37:25 网站建设 项目流程

刚学编程的时候,很多人觉得for循环不就是“for i in range(10)”嘛,三分钟就学会了。结果一到做练习题,碰到“打印九九乘法表”“求水仙花数”这种题目,脑子直接卡壳,完全不知道从哪里下手。这个现象我见过太多次了——语法看懂了不等于会写代码,会写代码的标志是能把实际问题翻译成循环结构

这篇内容就是围绕for循环的代码练习题展开的,不追新不炫技,老老实实把循环里最核心的“套路”掰开揉碎讲清楚:怎么用range控制次数、怎么用累加器做求和、怎么用嵌套循环解决二维问题、怎么避开那些看起来没毛病一跑就报错的坑。适合刚学完循环语法、做题经常没思路的Python初学者,也适合准备计算机二级或Python考级的同学用来查漏补缺。

1. 为什么“看懂了for循环”却做不出练习题

很多初学者都会经历这个阶段:for循环的语法书上一看就懂,range函数也会用,但面对空白的编辑器就是写不出东西来。原因其实不在于“不懂for循环”,而在于没有建立“用循环解决问题的思维路径”

1.1 语法层和应用层之间缺了一座桥

语法层的for循环很简单:

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

这段代码没有任何初学者看不懂。但应用层的题目是这样的:

求1到100之间所有偶数的和。

很多人的第一反应不是“从1循环到100,判断每个数是不是偶数,是偶数就累加”,而是“这个题该用什么函数来着”。这就是典型的缺乏将问题拆解为循环步骤的能力

做循环练习题,核心要养成的习惯是三步拆解法:

  1. 循环什么:确定要遍历的对象是什么(数字区间、列表元素、字符串字符等)。
  2. 每次循环做什么:确定循环体内部要执行的具体操作(累加、计数、拼接、判断等)。
  3. 循环结束后做什么:确定最终结果如何输出(打印、返回、存储等)。

拿“求1到100之间所有偶数的和”举例——循环的是1到100的数字;每次循环判断“当前这个数是不是偶数,是的话加到一个变量里”;循环结束后把这个变量打印出来。想清楚这三步,代码自然就写出来了。

1.2 语法全都懂,但做不出题的另一个隐藏原因

还有一个常见的隐藏原因:对range函数的三种写法不够敏感

看到题目“打印1到10”,很多新手第一反应是for i in range(10),然后发现打印出来的是0到9,和题目要求对不上。其实range有三种常用写法:

range(10) # 生成 0 1 2 3 4 5 6 7 8 9 range(1, 11) # 生成 1 2 3 4 5 6 7 8 9 10 range(1, 11, 2) # 生成 1 3 5 7 9

这里的关键是range的结束值是不包含的,想要包含n,就得写range(1, n+1)。这个细节太容易出错了,后面我会专门用一节讲这些坑。

2. 吃透range函数的三种参数形态,先过基础关

for循环在Python里最常配合的就是range函数,理解range的完整用法是练习题能写对的前提。

2.1 range的完整参数拆解

range(start, stop, step)有三个参数:

参数含义是否必填默认值示例
start起始值(包含)可选0range(1, 5)从1开始
stop结束值(不包含)必填range(5)到4为止
step步长(可为负数)可选1range(1, 10, 2)取奇数

很多初学者认为“range(5)就是往5循环5次”,这么说虽然没错,但没抓住本质。range的本质是生成一个整数序列range(5)生成的序列是[0, 1, 2, 3, 4],循环的过程其实是挨个取出序列里的元素。

2.2 用range实现倒序遍历

练习题里经常出现“逆序输出”“从大到小”这样的要求,比如反向打印数字:

# 从10打印到1 for i in range(10, 0, -1): print(i)

range(10, 0, -1)的序列是[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]。注意这里结束值必须写0而不是1,因为stop是不包含的——很多人写range(10, 1, -1),发现1不见了,又去排查半天。

2.3 用range遍历列表下标

题目要求“利用下标访问列表”时,可以用range(len(列表))

scores = [88, 92, 79, 85, 96] for i in range(len(scores)): print(f"第{i+1}个学生的成绩是:{scores[i]}")

这种写法的优势在于循环体里能同时拿到下标i和值scores[i];如果只需要值本身,直接for score in scores更简洁。选择题里经常考这两种方式的区别,要能分清楚。

2.4 基础热身题:用for循环打印偶数

先来一道简单题练手——打印1到20之间的所有偶数。最直接的写法:

for i in range(1, 21): if i % 2 == 0: print(i)

但换个角度,其实用步长直接一步到位:

for i in range(2, 21, 2): print(i)

两种写法都能得到正确答案,区别在于前者是“遍历所有数字再筛选”,后者是“直接生成偶数序列”。这两种思路在后续做题中都会频繁用到,建议都要掌握。

3. 循环四件套:累加器、计数器、标志位、嵌套循环

做for循环练习题,翻来覆去就是在考四个基本套路。把这四个套路吃透,大概八成的循环题都能解出来。

3.1 累加器:求和类题目的核心模式

累加器是循环里最基础的应用,核心思路是:在循环外定义一个变量初始值为0,每次循环把一个新值“加”进去。

经典题:求1到100的和。

total = 0 for i in range(1, 101): total += i print(total) # 5050

其实这道题用等差数列求和公式(1+100)*100//2 = 5050一秒就能算出来,但练习题的目的不是算结果,而是让你掌握累加器的写法。把range(1, 101)换成range(1, n+1),代码就变成了“求1到n的和”,你再也不用逐个手算。

累加器还有一种变体是求乘积,这时候初始值要设成1而不是0——如果设成0,所有结果乘出来都是0,这又是一个经典错误:

# 求1到10的乘积(10的阶乘) result = 1 for i in range(1, 11): result *= i print(result) # 3628800

3.2 计数器:统计满足条件的个数

计数器本质上也是累加,只是每次“加”的不是数值,而是1。

经典题:统计100以内有多少个能被3整除的数。

count = 0 for i in range(1, 100): if i % 3 == 0: count += 1 print(count) # 33

计数器的关键在于:循环体里只在满足条件时才执行count += 1,判断条件的if是计数器的灵魂。这类题目的变体很多——统计字符串里元音字母的个数、统计列表里大于60分的成绩数量、统计一个整数里有几位数,本质都是这套逻辑。

3.3 标志位:检查“是否存在”类问题

标志位(flag)的典型应用场景是:要判断一个集合里是否满足某个条件,循环结束后根据标志位给出结论。

经典题:判断一个数是否为质数。

num = 37 is_prime = True # 先假设它是质数 for i in range(2, num): if num % i == 0: is_prime = False break # 找到一个因子就可以撤退了 print(f"{num}是质数" if is_prime else f"{num}不是质数")

这里的逻辑是:先假设成立,再找反例推翻。循环里一旦发现num能被i整除,就把标志位改成False并立即跳出循环——因为已经找到反例,没必要继续往下试了。这种“假设-推翻”的思维方式,在很多编程题里都通用。

3.4 嵌套循环:二维问题的处理武器

嵌套循环解决的是“需要同时关注两个维度”的问题。比如打印一个4行5列的星号矩形:

for row in range(4): for col in range(5): print("*", end="") print() # 这一行负责换行

这里row是外层循环,控制行数;col是内层循环,控制每行打印多少个星号。关键在print("*", end="")——end=""表示不换行,这样同一行的星号会连着输出;内层循环结束后再print()换行,开始下一行。

嵌套循环最常见的错误是把换行逻辑写错位置。记住一句话:外层循环走一次,内层循环走完一整轮。想清楚这个层次关系,打印三角形、菱形、乘法表都是同一套思路。

4. 经典题目精讲:从九九乘法表到水仙花数

这一节用几道高频经典题,把前面说的套路串起来。这些题在各类考级、笔试和面试里反复出现,建议每一道都自己先写一遍再看讲解。

4.1 输出九九乘法表(嵌套循环的入门试金石)

这个题目几乎出现在每一本Python教材的循环章节末尾:

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

输出效果:

1×1=1 1×2=2 2×2=4 1×3=3 2×3=6 3×3=9 ...

拆解一下:外层循环i决定“当前是第几行”,内层循环j的范围是range(1, i+1)——也就是第i行只打印i列,这才形成了三角形的形状。end="\t"用制表符对齐,输出更整齐。

如果你能独立写出这道题,说明你已经基本掌握了嵌套循环。

4.2 打印直角三角形和等腰三角形

乘法表的变体是打印各种星号三角形。先看直角三角形:

n = 5 for i in range(1, n + 1): print("*" * i)

这一行代码就能搞定,但有些教材和练习为了练嵌套循环,会写成这样:

n = 5 for i in range(1, n + 1): for j in range(i): print("*", end="") print()

等腰三角形稍微复杂一点,需要同时处理空格和星号的关系:

n = 5 for i in range(1, n + 1): # 先打印空格:数量是 n - i for j in range(n - i): print(" ", end="") # 再打印星号:数量是 2*i - 1 for k in range(2 * i - 1): print("*", end="") print()

空格数量和星号数量是两个独立的等差数列——空格是n-i个,星号是2*i-1个。这类题目考的就是你能不能把这层数量关系推导出来。

4.3 求水仙花数(遍历筛选的经典题)

水仙花数是指一个三位数,其各位数字的立方和等于它本身,例如153 = 1³ + 5³ + 3³

for num in range(100, 1000): hundreds = num // 100 tens = (num // 10) % 10 ones = num % 10 if hundreds**3 + tens**3 + ones**3 == num: print(num) # 153 370 371 407

这道题的关键在于如何从三位数中拆出百位、十位、个位。核心是整除//和取余%的配合:百位是num//100,十位是(num//10)%10,个位是num%10

这里有个小技巧:如果你不想记那么多套公式,可以倒过来想——三位数abc可以表示成100*a + 10*b + c,那么遍历所有可能的a、b、c,再验证a³+b³+c³是否等于100a+10b+c,也就是把百位、十位、个位各当成一层循环:

for a in range(1, 10): for b in range(0, 10): for c in range(0, 10): num = a*100 + b*10 + c if a**3 + b**3 + c**3 == num: print(num)

两种思路都能做对,但第二种思路用到了三层循环,对理解嵌套逻辑很有帮助。

4.4 斐波那契数列:循环和数学归纳法的结合

斐波那契数列的前两项是1、1,从第三项开始,每一项等于前两项之和:1, 1, 2, 3, 5, 8, 13...

用for循环输出前20项:

a, b = 1, 1 for i in range(20): print(a, end=" ") a, b = b, a + b

这里a, b = b, a + b是Python特有的同时赋值写法:右边的值先计算完,再统一赋给左边。所以a变成原来的bb变成原来的a+b,恰好完成“向前推进两项”的操作。

如果不使用同时赋值,就必须引入临时变量:

a, b = 1, 1 for i in range(20): print(a, end=" ") temp = a + b a = b b = temp

很多新手写成a = b; b = a + b,结果发现输出全变成了2——因为第一句执行后a已经变成了b,第二句的a + bb + b而不是原来的a + b。这个坑特别值得记下来。

4.5 猜数字小游戏:break和continue的实战用法

练习题里还经常涉及break(跳出整个循环)和continue(跳过本次循环,继续下一次迭代)。写一个简化版的猜数字游戏:

target = 7 for attempt in range(1, 6): # 最多猜5次 guess = int(input(f"第{attempt}次猜,请输入数字:")) if guess > target: print("猜大了") elif guess < target: print("猜小了") else: print(f"恭喜!猜对了,用了{attempt}次") break else: print("次数用完了,正确答案是", target)

注意这里的for...else...结构:当循环正常结束(没有被break中断)时,else分支会执行。如果用户5次都没猜中,就进入else打印提示。breakcontinue练习题里最典型的组合用法就是这样——break处理“提前结束”的场景,continue处理“跳过本次”的场景。

5. 这些坑每一个初学者都踩过:for循环避错清单

for循环的语法很简单,但实际写练习题的出错率依然很高。我总结了几类高频错误,这些坑几乎每个初学的人都踩过。

5.1 range的结束值永远取不到

题目要求“打印1到100”,写range(1, 100)就少了100——这是range的第一个大坑。记住:range(start, stop)包含start,但不包含stop

一个实用的核对方法:range(1, n)实际上生成了1、2、...、n-1这几个数。要包含n,就用range(1, n+1)。做题时如果发现输出总比预期少最后一个数,第一反应就该检查range的结束值。

5.2 在循环体内修改迭代变量,没用

初学者常常想通过“修改i”来控制循环次数:

for i in range(10): if i == 5: i = 100 # 想让循环提前结束?做不到! print(i)

输出结果是0, 1, 2, 3, 4, 5, 6, 7, 8, 9——把i改成100对循环没有任何影响。因为for i in range(10)的本质是:先把range(10)这个序列一次性生成好,然后按顺序取出序列里的元素赋给i,循环体里修改i,只是改了当前这个变量,并不会改变序列本身。想要控制循环提前结束,用break,不要试图改i

5.3 累加变量忘初始化

累加器必须在循环外初始化。如果把total = 0写在循环里面,每次循环都会把total清零重来:

total = 0 for i in range(1, 101): total += i # 正确写法:total 在循环外初始化

而写成下面这样就是错的:

for i in range(1, 101): total = 0 # 每轮都被清零 total += i

同理,计数器、连乘的初始值也要放在循环外。这个错误的隐蔽之处在于:小数据量可能碰巧对,数据量一大结果就乱了。

5.4 嵌套循环中print的位置搞错

嵌套循环里,打印换行符的位置决定了输出形状:

for i in range(3): for j in range(3): print("*", end="") print() # 这个print属于外层循环,负责每行结束换行

如果把print()放进内层循环,就会变成每个星号后面都换行,3×3的矩形就会输出9行星号,形状彻底乱掉。

5.5 用range(len(s))和直接用列表元素,到底怎么选

遍历列表时,直接for item in my_list能拿到元素,for i in range(len(my_list))能同时拿到下标和元素。很多练习题故意把这两者混着出,比如要求“把列表中所有偶数翻倍”,如果你在循环里又改列表又遍历下标,就要特别小心。

一个简单的选择标准:只需要读元素,用for item in;需要修改列表对应位置或同时用到下标,用for i in range(len(...))

nums = [1, 2, 3, 4, 5] for i in range(len(nums)): nums[i] *= 2 # 需要修改原列表,所以用下标遍历 print(nums) # [2, 4, 6, 8, 10]

5.6 一个综合检查思路:遇到循环报错怎么查

做题时遇到循环相关的错误,按这个顺序排查效率最高:

  1. 报错信息里有没有range相关的提示:检查结束值、步长是否为0。
  2. 结果比预期多一个或少一个数:优先检查range的start和stop是否写对。
  3. 变量名冲突:检查循环变量和外部变量是否重名,特别是拿i既做外层循环又做内层循环的变量,会互相覆盖导致逻辑错乱。
  4. 缩进错误:Python里循环体靠缩进区分,一眼扫过去看不清缩进层级就赶紧去检查tab和空格混用的情况。

6. for循环的思路迁移:同样的题,换个语言照样做

for循环不是Python独有的语法。看热词里出现了C++、JavaScript、Shell,说明很多人在不同语言里都要用for循环。虽然语法细节不同,但核心思路完全一样——遍历区间、累加、嵌套、控制流程。这里放几组对比,帮助有跨语言需求的读者掌握“换个语言照样做”的能力。

6.1 Python和C++的for循环对比

用打印九九乘法表举例:

// C++ 写法:标准三段式 for for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { cout << j << "×" << i << "=" << i * j << "\t"; } cout << endl; }
# Python 写法:range 直接生成序列 for i in range(1, 10): for j in range(1, i + 1): print(f"{j}×{i}={i*j}", end="\t") print()

C++的for (int i = 1; i <= 9; i++)可以拆成三部分:初始化、循环条件、每轮更新。Python的for i in range(1, 10)则把“生成符合条件的数字序列”这个任务交给了range。在理解层面上,C++的方式更像在“控制循环条件”,Python的方式更像在“遍历一个序列”,但两者最终的执行逻辑是一致的。

6.2 JavaScript 和 Shell 里的 for 循环

JavaScript的for循环和C++几乎一样:

// JavaScript for (let i = 1; i <= 9; i++) { let row = ""; for (let j = 1; j <= i; j++) { row += j + "×" + i + "=" + i * j + "\t"; } console.log(row); }

Shell脚本里则常见这种遍历数字区间的写法:

#!/bin/bash for i in $(seq 1 9); do for j in $(seq 1 $i); do printf "%d×%d=%d\t" "$j" "$i" "$((i*j))" done echo "" done

seq 1 9生成1到9的序列,功能和Python的range(1, 10)是一样的。所以无论你换到哪种语言,核心都是理解“遍历一段数字区间,在循环体内做处理”这个模型,具体语法查一下文档就能上手。

6.3 循环结构练习题中常见的变体:for…else和while

Python有别于C系语言的一个特殊结构是for...else...,前面猜数字的例子里已经用过了。它的执行逻辑:如果循环正常跑完(没被break打断),就执行else里的代码;如果中途break了,就不执行

很多初学者第一眼觉得这结构没用,但它在“查找类”任务里很顺手——查一个数是否在某个范围内满足条件,找到了就break,没找到就进else。等价功能用C++写需要一个额外的标志位变量,用Python写可以少两行代码。

另外,forwhile的选择也是一道常考的练习题。一个简单的判断标准:遍历已知序列或确定次数用for;循环次数不确定、需要根据某个条件决定是否继续,用while。例如“猜数字直到猜对为止”用while更自然,因为不知道要循环几次;而“猜5次”用for更清晰,因为次数固定。

7. 从练习到实战:五个综合练习题测一测你的循环水平

最后放一组阶梯式综合题,从简到难,覆盖累加、计数、嵌套、标志位、break/continue这些知识点。建议每道题都先独立思考并写代码,再对照参考思路。能把这五道题完整无错地写出来,for循环这一关就算真正过了。

7.1 基础级:求1到n之间所有奇数的平均值

n = 30 total = 0 count = 0 for i in range(1, n + 1): if i % 2 == 1: total += i count += 1 print(total / count)

这道题同时用到累加器和计数器,是循环最基础的组合。

7.2 进阶级:统计一个字符串里每个字母出现的次数

s = "hello world" for char in set(s): # set(s) 得到不重复的字符集合 if char != " ": print(f"字符 {char} 出现 {s.count(char)} 次")

也可以用字典手动统计,顺便练一练dict和循环的配合:

s = "hello world" count_dict = {} for char in s: if char != " ": count_dict[char] = count_dict.get(char, 0) + 1 print(count_dict)

dict.get(char, 0)的含义是:取键char的值,如果不存在则用默认值0,然后加1再存回去。这是用循环统计数据出现次数的经典技巧。

7.3 进阶级:双层循环打印1到100的质数

for num in range(2, 101): is_prime = True for i in range(2, num): if num % i == 0: is_prime = False break if is_prime: print(num, end=" ")

这是“标志位+嵌套循环+break”的综合应用,能独立写出来说明已经掌握了这三种核心套路。

7.4 挑战级:输出杨辉三角的前10行

杨辉三角是嵌套循环和列表结合的经典题:

n = 10 row = [1] for i in range(n): # 打印当前行 print(" " * (n - i) + " ".join(map(str, row))) # 计算下一行:两两相加,首尾补1 next_row = [1] for j in range(len(row) - 1): next_row.append(row[j] + row[j+1]) next_row.append(1) row = next_row

这里的内层循环用上一行的相邻两个元素相加,推导出下一行。画出示意图会更好理解:每个数是它左上方和右上方的两个数之和。

7.5 挑战级:二分查找的循环实现

二分查找本身更适合用while,但用for也能实现——用多层循环控制区间缩小。经典的双重循环模型:

# 已排序数组 nums = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] target = 13 left, right = 0, len(nums) - 1 found = False while left <= right: mid = (left + right) // 2 if nums[mid] == target: print(f"找到了,下标是{mid}") found = True break elif nums[mid] < target: left = mid + 1 else: right = mid - 1 if not found: print("没找到")

while和for在这个场景下是可以互相转化的:已知区间长度、每次缩短一半,循环次数是log₂(n)级别的,用for也能写,但while表达“不断缩小查找区间”这个语义更自然。

写到最后:我把这些年的经验浓缩成三句话

做了这么多年编程教学,也带过很多从零开始的学员,对for循环练习这件事,我的体会可以浓缩成三句话。

第一句:做题练的不是语法,是“把问题拆成循环步骤”的思维。拿到题目先别想怎么写代码,先在纸上回答三个问题——循环什么、每次做什么、结束后做什么。这三个问题想清楚,代码基本就成型了。

第二句:九九乘法表、打印三角形、水仙花数这些经典题,值得反复写。很多人觉得这些题目太老套,其实它们精准覆盖了循环的所有核心套路:累加、计数、嵌套、筛选、遍历。一个能把乘法表写出三种写法的人,考试里碰到任何循环题都不会慌。

第三句:遇到报错别急着改,先重新读一遍自己的循环条件。初学者花在调试上的时间,有一半是浪费在range结束值、缩进、初始化位置这些细节上的。所以每做完一道题,建议回头检查一次:range写对没有?累计变量初始化没有?print的位置该在外层还是内层?

for循环不只是给编程学习者练手用的。在实际工作中,处理批量数据要循环,读取文件要循环,写爬虫翻页要循环,做自动化测试也要循环。练好这些练习题,等于给未来的实战打下了一个坚实的地基。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询