第 8 课 · 嵌套循环

画一个圣诞树

循环里再套循环:外层管行、内层管列,一层层画出矩形、三角形,最后拼出一棵漂亮的圣诞树。

120 分钟完整闭环 4 个知识点 5 段示范代码 难度 ★★★
🏠 学期课件主页 ← 上一课:循环进阶下一课:逻辑运算 →
01

本课导览

先看这节课教什么、怎么分配 120 分钟,老师心里有底,课堂节奏就不乱。

第8课嵌套循环
🎯 趣味项目:画一个圣诞树
嵌套循环外层/内层执行顺序图案打印
🎯教学目标(学完这节课,学生能…)
  • 理解嵌套循环的概念——循环里面还可以有循环;
  • 掌握嵌套循环的执行顺序:外层走一次,内层走完整的一轮;
  • 会用外层循环控制行数、内层循环控制每行内容,打印矩形、三角形等图案;
  • 能综合运用空格和星号,独立打印出一棵圣诞树;
  • 通过「图案越来越复杂」的递进练习,体会把大问题拆成小循环的思维方式。
🔑 教学重点
  • 外层循环管行数,内层循环管每行打什么
  • 执行顺序:外层走 1 次 → 内层从头到尾走完 → 再回到外层走第 2 次
🧗 教学难点 / 易卡点
  • 内层循环的次数和外层变量 i 挂钩(range(i)、range(2*i-1))时理不清
  • 圣诞树的「空格 + 星号」两段内层循环怎么配合
  • end="" 不换行与 print() 换行的配合时机
🧰课前准备(老师 / 学生)
  • 老师:提前运行圣诞树程序,确认控制台能正常显示;准备彩纸剪的圣诞树图片或实物做导入。
  • 学生:打开作品文件夹;今天作品保存为「第8课_圣诞树.py」。
  • 课堂小活动:让学生在方格纸上先画出圣诞树,数一数第几行几个空格、几个星号,再写代码——「先画图、再数数、后写码」。
⏱️120 分钟教学流程(建议时间轴,可按班级情况微调)
时间环节做什么 / 师生互动要点
0–5候课 · 设备检查开机 → 打开编辑器 → 确认作品文件夹就位。
5–12上节回顾 · 快问快答while 和 for 怎么选?break 干什么?怎么避免死循环?猜数字谁猜得次数最少?
12–22情景导入展示方格纸圣诞树,问:一行行手写太累,能不能让循环「造」出这棵树?引出循环套循环。
22–35知识讲解什么是嵌套循环 → 用时钟/日历讲执行顺序(外层 1 次 = 内层 1 轮)→ 外层管行、内层管列。
35–55示范代码 + 上机(示例1~3)矩形 → 直角三角形 → 等腰三角形,三步递进,每步都先数格子再写码。
55–75主项目:圣诞树先拆解:三角形树冠(含空格)+ 树干 → 老师带读 → 学生敲 → 改 height 看树长大。
75–88课堂练习 A/B练习 1 改 height 观察变化;练习 2 倒直角三角形;投屏典型错误找茬。
88–98挑战练习 C打印菱形;学有余力的同学给圣诞树加「星星树顶」或装饰字符。
98–106闯关小测外层 3 次内层 2 次共几次?内层次数怎么和外层挂钩?end="" 干嘛的?……
106–115总结 · 保存作品齐读口诀;保存「第8课_圣诞树.py」;强调「外层行、内层列」的心法。
115–120布置作业 · 预告布置必做/选做/思考;预告第 9 课:and/or/not 逻辑运算——让条件判断更聪明,做闰年判断器!

时间轴把 2 小时切成 8 段:复习→导入→讲解→示范→上机→练习→检测→小结,每段都有明确产出。

02

情景导入 · 复习热身

先用 5 分钟把上节课的记忆叫醒,再用故事和类比把新知识挂到孩子已有的经验上。

🔁上节回顾 · 快问快答(建议 5 分钟)

问 1:for 循环适合什么任务?while 呢?
→ for 适合知道次数的;while 适合靠条件停的(猜数字)。两种循环是重复任务的两员大将。

问 2:break 跳出循环后,程序去哪儿了?
→ 跳到整个循环后面的第一行继续执行。while True + break 猜对即停。

问 3:倒计时程序里「刹车」是哪一行?
→ n = n - 1,让条件 n > 0 最终变假——没有刹车的循环 = 死循环。

📖情景故事 · 今天学什么

新年快到了,班里要布置教室。小刚领到任务:用彩灯在窗户上摆一棵圣诞树。

他先摆了树冠——最上面 1 颗星,第二行 3 颗,第三行 5 颗……他摆着摆着发现规律:每往下一行,就多 2 颗。

小刚偷了个懒:能不能让同桌小美站在椅子上,按「第几行摆几颗」的口令帮他摆?小美气得直瞪眼:你把我当循环用啊!

小刚一拍脑门:对啊!我只需要外层数到第几行,内层按行数摆灯——这不就是循环套循环吗?

今天,就用 Python 的嵌套循环,在屏幕上种出一棵会自己长大的圣诞树!

💡生活类比:把新知识挂在旧经验上
🕰️

嵌套循环 = 分针和秒针

分针走 1 格(外层 1 次),秒针要走满 60 格(内层一整轮)。

外层1次=内层1轮
📅

执行顺序 = 日历翻页

月份是外层,日期是内层:1 月过完 31 天,才轮到 2 月的第 1 天。

一层层往里钻
📄

外层行内层列 = 写字板

一行一行往下写(外层),每一行从左往右写满(内层),写完一行换行。

行与列
🌲

圣诞树 = 空格+星号的算式

先打「树宽-行号」个空格把它推到中间,再打「2×行号-1」个星号。

两段内层循环
🗝️本课核心口诀(板书 / 齐读)
核 心 口 诀嵌套循环像时钟,外层走格内层圈;
外层管行内管列,空格星号拼图案!
03

知识讲解

分小块讲透语法点,每一块都配生活类比 + 要点小结,讲完立刻口头小试。

🕰️什么是嵌套循环?

在一个循环的里面再写一个循环,就叫嵌套循环。循环体里不只有 print,还可以是另一个 for/while。

看名字就懂:nest(窝)+ 循环 = 循环里「窝」着循环。就像套娃,大娃肚子里有小娃。

写法很简单:外层循环的缩进块里,再写一个完整的内层循环(它自己也要有冒号 + 缩进)。

经典例子:打印一个 5 行 3 列的矩形——外层循环 5 次管 5 行,内层循环 3 次管每行 3 个星号。

循环体里再写一个循环内层循环要整体缩进格式 = 冒号 + 缩进,层层递进
💡 写嵌套循环时,缩进就是「辈分」:外层是小弟们的班长,内层是班长的下级。别让它们站错队。
📅嵌套循环的执行顺序

嵌套循环怎么走?记住一句话:外层走一次,内层走完整的一轮。

举例:外层 i 从 1 到 3,内层 j 从 1 到 2。执行顺序是:i=1 时 j=1、j=2;i=2 时 j=1、j=2;i=3 时 j=1、j=2。

一共执行 3 × 2 = 6 次 内层代码。想算总次数?外层次数 × 内层次数。

内层循环的次数可以是固定的(矩形:每行都 3 个),也可以是跟外层 i 挂钩的(三角形:第 i 行打 i 个)——挂钩写法是打印图案的关键。

外层 1 次 → 内层整轮总次数 = 外层 × 内层内层次数可变(随 i 变)
💡 在纸上画个 3×2 的格子表,用箭头模拟 i、j 的走动顺序,比盯屏幕更直观。
🌲用嵌套循环打印图案

所有字符图案都能拆成两件事:外层循环控制行数,内层循环控制每行打印什么。

直角三角形:第 1 行打 1 个星、第 2 行打 2 个……所以内层写 range(i)——i 是几就打几个。

等腰三角形 / 圣诞树:先打空格把星号推到中间,再打星号。第 i 行空格数 = 总行数 - i,星号数 = 2×i - 1。

每打完一行要 print() 换行(单独一行、不带内容);想让星号连着不换行,print 里要写 end=""。

外层管行数内层管每行内容空格推位置,print() 换行,end="" 不换行
💡 先在小方格纸上画好图案、数清每行空格和星号的数量规律,再写代码——想不清楚别急着敲。
04

示范代码 · 动手做

老师先带读代码、讲注释,再让学生亲手敲一遍——敲错正好学习调试。

Python示例 1 · 图案 1:矩形(5 行 × 3 列)
# 第8课:嵌套循环——打印矩形
for i in range(5):        # 外层:5行
    for j in range(3):    # 内层:每行3个星号
        print("*", end="")   # 不换行,连着打
    print()               # 一行打完,换行
运 行 结 果
***
***
***
***
***
✍ 把内层 range(3) 改成 range(6),矩形变多宽?外层 range(5) 改成 range(8) 呢?

🤔 想一想:end="" 是什么意思?如果没有它,每打一个星号就换行,会变成什么样子?

Python示例 2 · 图案 2:直角三角形
# 直角三角形:第i行打i个星号
for i in range(1, 6):     # 外层:5行
    for j in range(i):    # 内层:打i个(跟外层挂钩!)
        print("*", end="")
    print()
运 行 结 果
*
**
***
****
*****
✍ 对照执行顺序数一数:第 3 行(i=3)内层循环几次?总星号数 1+2+3+4+5=15,运行验证。

🤔 想一想:如果内层写成 range(5) 而不是 range(i),图案会变成什么?(矩形!)

Python示例 3 · 图案 3:等腰三角形(先空后星)
# 等腰三角形:每行先打空格,再打星号
for i in range(1, 6):         # 5行
    for j in range(5 - i):    # 空格:5-i个
        print(" ", end="")
    for j in range(2 * i - 1):  # 星号:2i-1个
        print("*", end="")
    print()
运 行 结 果
    *
   ***
  *****
 *******
*********
✍ 把空格那段的 range(5 - i) 改成 range(0),三角形是不是贴到左边了?空格就是「推位置」的手。

🤔 想一想:第 4 行(i=4)有几个空格、几个星号?套公式 5-i 和 2i-1 算算再验证。

Python示例 4 · 主项目:圣诞树
# 第8课主项目:圣诞树
# 树冠 = 等腰三角形(height行)+ 树干
height = 6   # 树冠有几层,改这个数树就变高

# ---- 树冠:等腰三角形 ----
for i in range(1, height + 1):
    for j in range(height - i):    # 空格
        print(" ", end="")
    for j in range(2 * i - 1):     # 星号
        print("*", end="")
    print()

# ---- 树干:2行 x 3个星号 ----
for i in range(2):
    for j in range(height - 2):    # 空格(和树冠底部对齐)
        print(" ", end="")
    print("***")
运 行 结 果
     *
    ***
   *****
  *******
 *********
***********
    ***
    ***
✍ 把 height 改成 8,看树长高。数一数树冠底部几个星号,树干几个星号,想想怎么让树干「站」在树冠正中间。

🤔 想一想:树干为什么要打 height - 2 个空格?树冠底部是 2×height-1 个星号,树干是 3 个,怎么算差值?

Python示例 5 · 挑战示例:菱形(上半 + 下半)
# 挑战:菱形 = 上半等腰三角形 + 下半倒三角形
for i in range(1, 6):        # 上半:5行
    print(" " * (5 - i) + "*" * (2 * i - 1))
for i in range(4, 0, -1):    # 下半:4行,i从4倒到1
    print(" " * (5 - i) + "*" * (2 * i - 1))
运 行 结 果
    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *
✍ 这一版用字符串重复写法(第 6 课学过)。对照上下两半,想想为什么要 range(4, 0, -1) 倒数。

🤔 想一想:能不能把下半改成 range(1, 5) 的循环,用 (5-i) 或 (4-i) 之类凑出来?试试哪种更好写。

05

易错提醒

把最容易翻车的写法先亮出来,见一次、错一次、就会了。

易错点 1

内外层缩进搞混,代码「站错队」

✗ 错误写法
for i in range(3):
for j in range(2):
    print("*")
✓ 正确写法
for i in range(3):
    for j in range(2):
        print("*")
为什么:Python 靠缩进认辈分。内层循环必须比外层多缩进一格,否则要么报错、要么行为完全不对。
易错点 2

忘记 print() 换行,星号糊成一行

✗ 错误写法
for i in range(5):
    for j in range(3):
        print("*", end="")
✓ 正确写法
for i in range(5):
    for j in range(3):
        print("*", end="")
    print()
为什么:print(..., end="") 是「不换行连着打」。想分行,必须在每行结束后单独来一个空的 print() 换行。
易错点 3

内层循环次数写死,打不出三角形

✗ 错误写法
for i in range(1, 6):
    for j in range(5):
        print("*")
✓ 正确写法
for i in range(1, 6):
    for j in range(i):
        print("*")
为什么:三角形每一行星号数不一样,内层次数要跟外层 i 挂钩:range(i)。写死 range(5) 每行都一样多,就成矩形了。
06

课堂练习(分层)

基础题人人过关,进阶题鼓励尝试,挑战题给学有余力的孩子。参考答案给老师做巡视对照。

A组 · 基础(人人必做)课堂完成,老师巡回指导
  1. 运行圣诞树程序,把 height 改成 4、6、8 各运行一次,观察树的大小变化。 (提示:只改 height = 后面那个数。)
  2. 抄写并运行「矩形」和「直角三角形」两段代码,在注释里写明:哪行是外层、哪行是内层。 (提示:外层管行数,内层管每行内容。)
B组 · 进阶(鼓励尝试)课堂完成,老师巡回指导
  1. 用嵌套循环打印倒直角三角形:5 行,星号逐行减少。 (提示:内层 range(6 - i) 或让行号反过来。)
  2. 打印 5 行「数字三角形」:第 1 行 1,第 2 行 12,第 3 行 123…… (提示:内层打印 j,j 从 1 到 i;用 end="" 连着打。)
C组 · 挑战(学有余力)课堂完成,老师巡回指导
  1. 用嵌套循环打印一个菱形(先打上半 5 行,再打下半 4 行)。 (提示:下半用 range(4, 0, -1) 倒着走。)
  2. 打印空心矩形:5 行 7 列,只有边框是星号,中间是空格。 (提示:第一行和最后一行全打星;中间行只打首尾两个星。) 参考答案:用 if 判断 i 是不是第一/最后一行。
07

闯关小测

收尾前 10 分钟,用口答 / 举手抢答把今天的关键点过一遍。

闯关 1先举手回答,再对答案

嵌套循环里,外层走 1 次,内层要走几次?

答案:内层走完整的一轮(所有次数)。

💡 外层 3 次 × 内层 2 次 = 共 6 次。

闯关 2先举手回答,再对答案

外层 3 次、内层 4 次,内层代码总共执行多少次?

答案:12 次(3 × 4)。

💡 总次数 = 外层次数 × 内层次数。

闯关 3先举手回答,再对答案

打印图案时,外层循环管什么?内层管什么?

答案:外层管行数,内层管每行打印什么。

💡 行和列的分工。

闯关 4先举手回答,再对答案

print("*", end="") 和 print("*") 有什么区别?

答案:前者不换行、星号连着打;后者打完换行。

💡 想分行要在内层结束后用 print() 换行。

闯关 5先举手回答,再对答案

等腰三角形第 i 行:空格数和星号数怎么算(共 5 行)?

答案:空格 5-i 个,星号 2×i-1 个。

💡 先推位置(空格),再画身体(星号)。

08

小结 · 作业与预告

用一句话带走今天的内容;作业分层布置,作品记得保存进成长档案。

🖍️本课小结(一句话 + 板书核心词)
一句话带走循环里再套循环:外层管行、内层管列,一层层画出矩形、三角形,最后拼出一棵漂亮的圣诞树。
嵌套循环 = 循环套循环外层1次=内层1轮外层管行 / 内层管列总次数 = 外×内内层次数挂钩 iend="" 不换行 / print() 换行空格推位置
必做 · 人人过关
  1. 必做题:用嵌套循环打印 5 行数字三角形:第 1 行 1,第 2 行 12,第 3 行 123……第 5 行 12345。
  2. 把圣诞树保存为「第8课_圣诞树.py」放进作品文件夹,并把 height 调成 8 运行一次(老师检查)。
选做 · 鼓励挑战
  1. 选做题:打印一个空心矩形——边框是星号,里面是空格(例如 5 行 7 列)。
  2. 选做题:给圣诞树加一颗「星」:树顶正上方打一个特殊符号(如 ★ 或 $),并给树加个树根。
思考 · 烧脑一下
  1. 思考题:外层循环 10 次、内层 5 次,内层代码总共执行几次?如果再套一层 3 次的循环呢?
  2. 想一想:打印图案时,为什么「先打空格」能把星号推到中间?如果先打星号再打空格会怎样?
👉 下节课预告:下一课《逻辑运算》:学 and/or/not 三个逻辑词,把多个条件组合成一句话——做出准确的闰年判断器!