这一篇会让读者真正感受到,循环一旦“套起来”,程序能做的事情会一下子多很多。
前面你已经学会了两种循环:
whilefor
你也学会了 range(),知道怎么控制循环次数。 还学了 break、continue、pass,知道循环中途怎么更灵活地处理。
到这里,单层循环你已经有基础了。
可真实程序里,很多场景不是“只重复一层”就够的。 有时候,你需要:
外面先循环一轮 里面再循环一轮
这就像什么。
比如你整理班级座位表:
先看第 1 排 第 1 排里再看每个座位
再看第 2 排 第 2 排里再看每个座位
这就是一种非常典型的“循环里再套循环”的结构。
这就是今天要讲的内容:
循环嵌套
很多教程讲到这里时,最喜欢举的例子就是九九乘法表。 这个例子当然很经典。 但你要知道,九九乘法表只是循环嵌套最基础的练习之一。 真正重要的是,你要借它理解:
一层循环控制大方向 另一层循环控制细节
一、什么是循环嵌套
先说最直白的理解。
循环嵌套,就是在一个循环里面,再写一个循环。
比如:
for i in range(3): print('外层循环开始')for j in range(2): print('内层循环执行')
这里就出现了两层循环:
外层 for内层 for
程序执行时,不是先把外层全部跑完再跑内层。 而是:
外层每跑一轮, 内层都要完整跑一遍。
这就是循环嵌套最核心的运行方式。
二、先用一个最简单的例子感受“外层一轮,内层一整遍”
来看这段代码:
for i in range(3): print(f'外层第{i}轮开始')for j in range(2): print(f' 内层第{j}轮')
输出大概会是:
外层第0轮开始 内层第0轮 内层第1轮外层第1轮开始 内层第0轮 内层第1轮外层第2轮开始 内层第0轮 内层第1轮
你要重点体会这个节奏:
外层第 0 轮 内层跑完 0、1
外层第 1 轮 内层再跑完 0、1
外层第 2 轮 内层再跑完 0、1
也就是说:
内层循环会随着外层循环的每一轮,完整重复一遍
这个节奏一旦理解了,后面很多嵌套循环都不会太难。
三、可以把循环嵌套理解成“二维处理”
单层循环更像在处理“一条线”。
比如:
从 1 到 5 一句话里的每个字 一个列表里的每个元素
而嵌套循环,更像在处理“行和列”“层和层”“组和组”。
比如:
座位表的每一排和每一列 表格的每一行和每一列 班级的每个小组和组内每个成员 每天的每个小时 每个学生的每门成绩
所以嵌套循环特别适合处理:
成组的数据 分层的结构 二维的规律
你现在先不用急着想太复杂, 只要建立一个感觉就行:
单层循环像一条线 嵌套循环像一个面
四、最经典的入门例子:打印方块
先别急着上九九乘法表, 我们先从一个更容易看懂的例子开始。
比如打印一个 3 行 4 列的星号方块:
for i in range(3):for j in range(4): print('*', end='') print()
输出结果会是:
************
这段代码特别值得你认真看懂。
外层循环:
for i in range(3):
表示一共做 3 行。
内层循环:
for j in range(4): print('*', end='')
表示每一行打印 4 个星号。
内层结束后:
print()
表示换行。
所以整体逻辑就是:
每一行打印 4 个星号 一共打印 3 行
这就是循环嵌套特别经典的“行列结构”。
五、这里第一次出现了一个新东西:end=''
你会注意到,刚才代码里有一句:
print('*', end='')
前面我们一直直接用 print(),一打印就换行。 但这里如果每打印一个星号都换行,就不对了。
所以这里用了:
end=''
它的意思是:
打印完以后,先不要自动换行
这样一来,4 个星号就会排在同一行。
而后面的:
print()
才是真正负责换行。
你现在先记住最实用的结论就行:
print(..., end='')表示打印后不换行
print()单独写一行,常用来换行
这个知识点在打印图形、表格、乘法表时会特别常用。
六、自己动手做一个打印方块练习
下面这段代码建议你现在就敲一遍。
for i in range(3):for j in range(5): print('*', end='') print()
运行结果会是:
***************
然后你自己改两个地方试试。
把 3 改成 4 把 5 改成 2
看看结果会变成什么样。
你会发现:
外层数字控制行数 内层数字控制每行有多少个元素
这个感觉一旦建立起来,嵌套循环就会顺很多。
七、外层控制“做几行”,内层控制“每行做几次”
这是当前阶段最重要的一句话之一。
比如刚才这个例子:
for i in range(3):for j in range(5): print('*', end='') print()
你可以直接这么理解:
外层 3 次 所以有 3 行
每一行里,内层 5 次 所以每行有 5 个星号
所以以后你再看到类似结构, 脑子里要很快形成这个翻译:
外层定大框架 内层定每个框架里的细节
这个思维非常重要。
八、先做一个“数字矩形”的练习
别总是打印星号,我们来换点内容。
比如:
for i in range(3):for j in range(4): print(j, end=' ') print()
输出会是:
012301230123
这里内层打印的是 j, 所以每一行都会显示:
0、1、2、3
然后外层循环重复 3 行。
这个例子特别好, 因为它会让你更明显地看到:
内层变量 j 在变 外层变量 i 控制整轮重复
九、再做一个“行号 + 列号”的练习
这个练习特别有助于理解外层和内层各自负责什么。
for i in range(3):for j in range(4): print(f'({i},{j})', end=' ') print()
输出会类似这样:
(0,0) (0,1) (0,2) (0,3) (1,0) (1,1) (1,2) (1,3) (2,0) (2,1) (2,2) (2,3)
你从这个结果里会看得特别清楚:
外层变量 i 先固定住 内层变量 j 在这一行里不断变化
等内层跑完一整轮, 外层变量 i 才进入下一轮
这个练习对理解嵌套循环的运行顺序特别有帮助。
十、现在来讲最经典的九九乘法表
先上代码:
for i in range(1, 10):for j in range(1, i + 1): print(f'{j}×{i}={i*j}', end=' ') print()
输出结果会是:
1×1=11×2=22×2=41×3=32×3=63×3=9...1×9=92×9=18 ... 9×9=81
这个例子为什么经典。
因为它把嵌套循环的两个层级体现得特别清楚:
外层控制第几行 内层控制这一行里打印几项
具体来说:
外层:
for i in range(1, 10):
表示从第 1 行到第 9 行。
内层:
for j in range(1, i + 1):
表示当前这一行打印从 1 到 i 的内容。
所以:
第 1 行打印 1 项 第 2 行打印 2 项 第 3 行打印 3 项 …… 第 9 行打印 9 项
这就是九九乘法表的核心规律。
十一、为什么内层是 range(1, i + 1)
这个点很多新手第一次会有点绕。
比如外层来到:
i = 3
那这一行应该打印:
1×3 2×3 3×3
也就是说,内层要从 1 走到 3。
而 range() 的结束值是不包含的, 所以如果想让它取到 3,就得写:
range(1, 4)
也就是:
range(1, i + 1)
因为当前 i = 3,i + 1 = 4, 刚好能取到 1、2、3。
这个思路你最好真正理解, 不要只是机械记代码。
十二、先别急着背九九乘法表代码,先看懂它的运行节奏
来看第 3 行时会发生什么。
外层来到:
i = 3
于是进入内层:
for j in range(1, i + 1):
也就是:
for j in range(1, 4):
所以 j 会依次取:
1 2 3
每次打印:
1×3=32×3=63×3=9
打印完这一行以后, 执行一个:
print()
换行。
然后外层进入下一轮:
i = 4
再重新走一遍内层。
你只要把这个“外层换行、内层拼一行”的节奏看懂, 九九乘法表就不神秘了。
十三、自己动手做一个“简化乘法表”练习
先别一上来就 9×9。 我们先做 3×3:
for i in range(1, 4):for j in range(1, i + 1): print(f'{j}×{i}={i*j}', end=' ') print()
输出会是:
1×1=11×2=22×2=41×3=32×3=63×3=9
这个练习特别适合现在做。 因为规模小,容易看懂。
你等看懂了,再把 4 改成 10:
for i in range(1, 10):
自然就变成完整九九乘法表了。
十四、循环嵌套不只是乘法表,它还特别适合打印图形
比如打印直角三角形:
for i in range(1, 6):for j in range(i): print('*', end='') print()
输出结果:
***************
这里的逻辑就是:
第 1 行打印 1 个星号 第 2 行打印 2 个星号 第 3 行打印 3 个星号 ……
你会发现,这和乘法表非常像。
都是:
外层控制第几行 内层控制这一行打印几次
所以一旦你把这种“行数 + 每行次数”的思维掌握住, 图形打印、乘法表这类题就都会好很多。
十五、再做一个倒三角练习
比如:
for i in range(5, 0, -1):for j in range(i): print('*', end='') print()
输出会是:
***************
这个例子很有帮助, 因为它会让你意识到:
外层不一定非得从小到大 也可以倒着来
只要外层的变化规律变了, 内层每行打印的数量也会随之变化。
这就是嵌套循环很有意思的地方。
十六、嵌套循环里最怕什么
最怕两个问题。
第一,不清楚外层和内层各自控制什么。 结果写着写着,自己都不知道谁在负责行、谁在负责列。
第二,不会看运行顺序。 总觉得程序是“同时”在做很多事。 其实不是,它仍然是一轮一轮顺序执行的。
所以你现在最重要的,不是追求写很多花哨图形。 而是先把这两件事想清楚:
外层一轮到底表示什么 内层一整遍到底表示什么
只要这两个问题清楚, 嵌套循环就不会太乱。
十七、先用一句话概括嵌套循环的执行节奏
这个你一定要记。
外层每执行一轮, 内层就完整执行一遍。
比如:
for i in range(3):for j in range(2): print(i, j)
执行节奏是:
当 i = 0 时,j 跑完 0、1 当 i = 1 时,j 再跑完 0、1 当 i = 2 时,j 再跑完 0、1
不是外层跑完以后再整体跑内层。 而是每一轮外层,都会带着内层完整走一遍。
这一点特别关键。
十八、嵌套循环和变量名最好写清楚
比如你会经常看到:
for i in range(...):for j in range(...):
这没错,也很常见。 但当前阶段你如果还不熟,其实可以写得更清楚一点。
比如:
for row in range(3):for col in range(4): print(f'({row},{col})', end=' ') print()
这样一看就知道:
row 表示行col 表示列
对新手来说,这种命名方式有时候会更友好。
所以你不必被 i、j 绑死。 变量名写清楚,理解往往更轻松。
十九、实操,做一个“5 行 5 列数字表”练习
for row in range(5):for col in range(5): print(col, end=' ') print()
输出大概是:
0123401234012340123401234
然后你再改成打印行号:
for row in range(5):for col in range(5): print(row, end=' ') print()
你会发现结果完全不一样。
这个练习很有用, 因为它能帮助你体会:
外层变量和内层变量在输出里各自起什么作用
二十、实操,做一个“行列坐标”练习
这个练习特别推荐。
for row in range(3):for col in range(4): print(f'{row},{col}', end=' ') print()
输出会很像一个坐标表。
你做完以后,对“二维遍历”的感觉会强很多。
因为你会亲眼看到:
程序正在一行一行、一个位置一个位置地处理内容
这比单纯看概念更有用。
二十一、今天一定要亲手完成的 4 个练习
第一个,打印 3 行 4 列的星号方块。
for i in range(3):for j in range(4): print('*', end='') print()
第二个,打印直角三角形。
for i in range(1, 6):for j in range(i): print('*', end='') print()
第三个,打印 3×3 简化乘法表。
for i in range(1, 4):for j in range(1, i + 1): print(f'{j}×{i}={i*j}', end=' ') print()
第四个,打印行列坐标。
for row in range(3):for col in range(4): print(f'({row},{col})', end=' ') print()
这四个练习分别对应:
方块 三角形 乘法表 二维坐标
几乎把循环嵌套最基础的感觉都覆盖到了。
二十二、再做一个综合小练习
下面这个练习特别适合作为今天的收尾。
需求:
打印一个 1 到 5 的数字三角形。
代码如下:
for i in range(1, 6):for j in range(1, i + 1): print(j, end=' ') print()
输出结果会是:
112123123412345
这个例子非常好, 因为它同时融合了:
外层控制行数 内层控制每行打印数量 内层变量本身也参与输出内容
你一旦把这个练习跑顺, 循环嵌套的理解会明显上一个台阶。
二十三、写在最后
很多人第一次学循环嵌套时,会觉得它突然复杂了很多。 其实它并不是全新规则。 它只是把你已经学过的循环,再叠了一层。
单层循环解决的是:
重复一条线上的事情
嵌套循环解决的是:
重复一个面上的事情 或者说,处理带行列、带层次的结构
所以你现在最重要的,不是一下子写出所有复杂图形。 而是先把最核心的运行节奏真正看懂:
外层一轮 内层一整遍
只要这件事你脑子里清楚了, 后面很多看起来复杂的嵌套循环,其实都能拆开理解。
这一步非常关键。 因为从这里开始,程序处理复杂结构的能力,已经明显变强了。
本文小结
循环嵌套就是在一个循环里面再写一个循环。 它特别适合处理行列、层级、二维结构等场景。 最关键的执行规律是:外层每执行一轮,内层就完整执行一遍。 打印方块、三角形、九九乘法表,都是循环嵌套的经典练习。 学习循环嵌套最重要的,不是背代码,而是分清外层和内层各自控制什么。
下篇预告
第 29 篇,我们把这一阶段再往前推进一步。
推导出流程图思维:先想逻辑,再写代码
到那一篇,你会开始真正体会到:写程序不是先敲代码,而是先把步骤和流程想明白。