CC++ & Algorithm

Python 循环嵌套详解

困难2
语言版本:C++Python
概述:学会在一个循环里面再放一个循环,像钟表的时针和分针一样协同工作。

循环嵌套:让循环里再套一个循环,像钟表里的时针和分针

你有没有想过,为什么时钟的时针转一圈,分针要转12圈?这就是“嵌套”的含义——一个循环(时针)每走一步,另一个循环(分针)就要完整跑一圈。在Python中,我们可以在一个循环的“肚子”里再放一个循环,这种结构叫循环嵌套。它特别适合画表格、做重复的重复任务,比如打印一个图案、处理二维数据(像教室座位表)、做乘法表等等。

下面我们就用生活中的例子一步步学会它。


1. 什么是循环嵌套?——就像广播体操

想象操场做广播体操:每一遍(外层循环)由许多动作(内层循环)组成。做一遍广播体操,你把所有动作做一遍;然后开始下一遍,再把所有动作做一遍……重复若干遍。

在代码里,外层循环控制“第几遍”,内层循环控制“当前这遍里的每个动作”。内层循环先完全执行完,外层才进入下一轮。

最经典的入门例子是用星号打印一个矩形:

for i in range(3):          # 外层循环:做3遍(3行)
    for j in range(5):      # 内层循环:每遍做5个动作(5个星号)
        print("*", end="")  # 不换行,连续打印星号
    print()                 # 内层循环结束,换行(相当于做完一遍,换下一行)

输出:

*****
*****
*****

你可以这样理解:外层像班长喊“第1遍!”,内层就赶紧打印5个星号;然后班长喊“第2遍!”,内层又打印5个星号……直到3遍结束。


2. 内外循环的变量可以互相影响——打印直角三角形

内外循环的变量不是孤立的。内层循环的结束条件可以用外层变量的当前值,这样每行的内容不一样。比如打印数字三角形:

for row in range(1, 6):           # 外层:行号从1到5
    for col in range(1, row + 1): # 内层:列数等于当前行号
        print(col, end=" ")       # 打印当前列号,不换行
    print()                       # 一行结束,换行

输出:

1 
1 2 
1 2 3 
1 2 3 4 
1 2 3 4 5 

这里内层循环的range(1, row + 1)表示:第1行只打印1列,第2行打印2列……第5行打印5列。外层变量row就像一个指挥,告诉内层“这次你循环多少次”。

生活中的例子:你每天做俯卧撑,第一天做1个,第二天做2个,第三天做3个……外层循环是“天数”,内层循环是“当前天数里做的俯卧撑个数”。你不可能在第二天就做3个,因为内层循环的范围是由外层决定的。


3. 打印九九乘法表——嵌套循环的经典应用

九九乘法表是嵌套循环的“招牌菜”。它也是基于“外层控制行,内层控制列”,但内层结束条件依赖外层(行号)。回忆一下:

for i in range(1, 10):          # 外层:行号1到9
    for j in range(1, i + 1):   # 内层:列号从1到当前行号
        print(f"{j}x{i}={i*j}", end="\t")  # 格式化输出,用制表符对齐
    print()                     # 换行

输出:

1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
...

注意:内层循环j从1开始,到i结束,所以每行的算式数量正好等于行号。为什么不是j从1到9?因为乘法表是三角形的,不能打印成矩形(否则会出现1x3, 2x3, 3x3, 4x3... 但4x3在第四行才出现,而第三行只有三个算式)。


4. 小心性能陷阱——嵌套循环的“乘法效应”

嵌套循环的总执行次数 = 外层次数 × 内层次数。如果外层100次,内层100次,总共就是10000次。如果三层嵌套,次数会爆炸。

比如打印一个10×10的星号矩形:

for i in range(10):         # 外层10次
    for j in range(10):     # 内层10次
        print("*", end="")
    print()

总共打印了 10 × 10 = 100 个星号,还算好。但如果外层是1000,内层是1000,就变成100万次,程序会卡顿。

生活中的例子:假设你抄写数学题,每道题有5个小题(内层5次),一共有10道题(外层10次),你要抄 10 × 5 = 50 个小题。如果你有100道题,每道题100个小题,那就得抄10000个小题……手会断的!所以写嵌套循环前,先想想能不能用更简单的方法(比如列表推导式),或者确认真的需要这么多层。


5. 新手容易犯的错误

错误1:忘记内层循环结束后换行

如果不加print()换行,所有内容会挤在一行:

for i in range(3):
    for j in range(5):
        print("*", end="")  # 忘记换行

输出:

***************

错误2:内层循环的变量名和外层一样

如果内外层都用同一个变量名,比如都是i,内层会修改外层变量的值,导致外层循环混乱:

for i in range(3):        # 外层i
    for i in range(5):    # 内层也用i(覆盖了外层i的值)
        print(i, end="")
    print()

输出不是预期效果,因为内层循环结束后,i的值变成了4,外层无法正确进入下一次循环。务必用不同的变量名,比如外层用row,内层用col

错误3:内层循环范围用错导致无限循环

比如想打印5行5列,但内层条件写成while True或漏了更新条件,就会卡住。要仔细检查循环条件和步进。


6. 完整可运行的示例:打印一个倒直角三角形

结合前面的知识,我们来写一个完整程序:打印5行的倒直角三角形,第一行5个星号,第二行4个,……最后一行1个。

# 打印倒直角三角形:5行,每行星号数递减
rows = 5                        # 总行数
for row in range(rows, 0, -1):  # 外层:从5到1递减(每次减1)
    for col in range(row):      # 内层:当前行有几个星号
        print("*", end="")      # 打印星号,不换行
    print()                     # 换行

输出:

*****
****
***
**
*

思路:外层从5往下数到1,每行的星号数量就等于外层的当前值。内层循环次数刚好是row


7. 更多练习和延展

  • 打印空心矩形:除了边框,里面是空格。可以用嵌套循环判断是否在边界。
  • 打印菱形:需要上下两半,用两个嵌套循环组合。
  • 用嵌套循环处理二维列表:比如全班同学的成绩表格,外层遍历每个学生,内层遍历每门课的成绩。

掌握了嵌套循环,你就能画出各种有趣的图案和表格了!接下来可以学习 while 嵌套循环break 和 continue 在嵌套循环中的使用(注意:break只能跳出它所在的那一层循环),以及如何用列表推导式简化某些嵌套循环


相关知识点指引

(以上链接请根据实际知识库填充)

例题精讲

1单选题

执行以下代码,输出结果的个数是多少? for i in range(3): for j in range(2): print(i, j)

A3
B4
C5
D6
2单选题

以下代码的输出结果是什么? for i in range(2): for j in range(4): if j == 2: break print(i, j)

A0 0 0 1 1 0 1 1(每行一个)
B0 0 0 1 0 2 1 0 1 1 1 2
C0 0 0 1 1 0 1 1 1 2
D0 0 0 1 0 2 1 0 1 1
3判断题

在嵌套循环中,内层循环使用 continue,会跳过外层循环的本次迭代。

4填空题
以下代码打印一个由星号组成的直角三角形,补全内层循环的范围。

for i in range(5):
    for j in range(___):
        print('*', end='')
    print()
5填空题
以下代码输出九九乘法表的一部分(仅打印 i≤j 的上三角部分),补全内层循环的范围。

for i in range(1, 10):
    for j in range(i, ___):
        print(f"{i}*{j}={i*j}", end=' ')
    print()