嵌套循環(nested loop)

把「重覆做某件事」分成外層內層,用來處理格子、表格、圖案與二維資料;並學會用縮排清楚表達程式區塊,避免常見除錯陷阱。

一、學習目標

重點

  • 理解嵌套循環的角色分工:外層決定「做幾輪」,內層決定「每輪做幾次」。
  • 能用「格子/表格」視覺化理解:外層走列(row),內層走欄(col)
  • 掌握執行次序與總次數:內層本體通常執行 rows × cols 次。
  • 能用嵌套循環完成常見題型:圖案輸出、計數、加總、搜尋。
  • 能清楚說明縮排的重要性,並能針對嵌套循環常見錯誤進行除錯。

學嵌套循環最有效的方法不是死記語法,而是把它看成「兩個方向的重覆」。當你能把問題畫成格子(表格),你就已經掌握了嵌套循環的核心思維:外層走列,內層走欄

在本章,你不但會看見偽代碼與 Python 的對照,也會用可操作的小遊戲把執行次序「玩出來」:你會親手按「下一步」看到程式走到哪一格、甚麼時候換行、為甚麼總次數是 rows × cols

最後,你會特別學會縮排在 Python 中的重要性。縮排不只是美觀,它直接決定「哪一句在外層」「哪一句在內層」,因此也最容易成為嵌套循環除錯的關鍵。

二、概念引入:外層與內層在做甚麼?

重點

  • 把「rows×cols」想成表格:外層循環負責「第幾列」,內層循環負責「第幾欄」。
  • 內層循環每次都由頭跑到尾,然後外層才會進入下一輪。
  • 輸出圖案時,常見規則是:內層負責輸出「同一行的內容」,外層每輪結束後再換行。
  • 建議用清晰變量名:row/coli/j 更不易混淆。

你可以把嵌套循環看成「雙重節拍」:外層每拍一下,就讓內層完整跑完一次。這個節奏不會因題目不同而改變,改變的只是你在內層做甚麼(輸出、加總、計數、判斷)。

最直觀的應用是「輸出方格」:外層代表「行」,內層代表「每行的字元數」。只要你把換行(或輸出下一列)放在外層循環的末端,就能穩定地得到一行一行的輸出。

接下來,請先用下面的互動格子「玩一次」:你按一下「下一步」,就會看到內層如何在同一行逐格前進;當一行走完,程式才會回到外層並換行。

項目 外層循環(outer loop) 內層循環(inner loop)
主要責任 控制「做幾輪」(通常對應行/列 控制「每輪做幾次」(通常對應欄/格
常見變量名 rowr colc
最常見的輸出 每輪末尾做一次換行 輸出一個字元/處理一個格子
最常見錯誤 用錯上界、忘記外層更新 忘記重置內層計數器、縮排不正確

你而家「行緊」邊一格?

下一步觀察:內層先走完同一行的所有欄,然後才會換到下一行。

目前 row
目前 col
內層本體累計次數
0
提示:格子左上角顯示的是座標(row, col),這是視覺化用的;
真正的 Python 程式輸出會在程式碼下方的黑色輸出框顯示。

模擬輸出(像印方格一樣)

Python 小練習:印出 rows×cols 的方格

請先按 Run 程式(系統會要求你輸入 rows、cols),觀察輸出,再按 核對答案 用隱藏測試檢查。兩題做的是同一件事:第一題用 for loop,第二題用 while loop

練習 S0-1(for loop)

練習 S0-2(while loop)

Check Point 1:外層與內層的角色

重點

  • 外層通常對應「行/列」;內層通常對應「欄/格」。
  • 內層完成一次=同一行完成;然後外層才會進入下一行。
  • 答題時先畫格子,再對應 row/col,最不易錯。

小測:外層/內層分工

(載入中…)



      
    

三、執行次序與次數:為甚麼常見答案是 rows × cols?

重點

  • 若外層跑 rows 輪,而每輪內層跑 cols 次,內層本體合共跑 rows × cols 次。
  • 把「第幾次內層執行」對應到格子:可用追蹤表(trace table)釐清。
  • 常見掃描次序是 row-major:先行後列(同一行走完才到下一行)。
  • 除錯時可暫時輸出 row/col,用輸出定位「哪一步開始不對」。

當你能把嵌套循環想成「走格子」,你就會自然得出 rows × cols。因為每一格都會執行一次內層本體,而格子總數正是「列數 × 欄數」。

實戰除錯時,最有效的方法是建立追蹤表:把 rowcol 每一步的值寫下來(或暫時用 print 印出)。你會很快發現:錯誤往往不是在內層本體本身,而是「重置」或「更新」的位置放錯了。

下面有兩個互動練習:第一個是「次數計算器」,第二個是「步數 ↔ (row,col) 對應」。做完後,你會更有把握面對「問你執行幾次」這類題目。

總次數

內層本體(例如輸出一個字元)總共會執行:

rows × cols
計算結果
28

步數 ↔ 座標

以 row-major(先行後列)計:

row
(step − 1) // cols
col
(step − 1) % cols
對應 (row, col)
(1, 2)

Python 小練習:把『次數』與『座標』算出來

練習 S1-1:輸入 rows、cols,輸出內層本體總次數

練習 S1-2:輸入 rows、cols、step(由 1 開始),輸出 (row, col)(由 0 開始)

Check Point 2:總次數與追蹤表

重點

  • 內層本體總次數通常是 rows × cols
  • row-major 掃描:同一行走完才到下一行。
  • 追蹤表可協助找出「重置」與「更新」放錯位置的錯誤。

小測:次數與追蹤

(載入中…)



      
    

四、圖案輸出:嵌套循環 + 規則(if 條件)

重點

  • 圖案題通常分兩步:先寫嵌套循環骨架,再在內層加入 if 規則決定輸出甚麼。
  • 內層輸出通常要「不換行」,外層每輪末尾才換行。
  • 常見規則:row == col(對角線)、(row+col)%2(棋盤格)、邊框判斷(row=0 或 row=rows-1 或 col=0 或 col=cols-1)。
  • 善用表格視覺化:先在紙上圈出要輸出的格子,再翻譯成條件。

圖案輸出其實是一種「逐格判斷」:你走到哪一格,就判斷那一格應該輸出甚麼。只要你能把圖案畫成格子,你就能把規則翻譯成 if 條件。

學習時,請先把注意力放在兩件事:第一,換行是否只在外層末尾出現;第二,if 條件是否只影響「輸出內容」,而不影響走格子的次序。

下面的「圖案實驗室」可以讓你選擇不同規則並點擊任意格子,看清楚該格的 (row,col) 以及為何被判定為輸出/不輸出。

規則說明

你點擊的格子

(row, col)
判斷結果
做題提示:先用小 n(例如 4 或 5)觀察規則,再把規則寫成 if 條件。

Python 小練習:兩個常見圖案

練習 S2-1:棋盤格(for loop)

練習 S2-2:靠左直角三角形(while loop)

以下示範「輸出靠左直角三角形(高度 n)」的 4 種偽代碼循環寫法(DSE 常見)。

讀入 n
設 row 由 1至 n
    設 col 由 1至 row
        輸出 "*"(不換行)
    輸出換行

Check Point 3:圖案輸出與換行位置

重點

  • 內層輸出通常不換行;外層末尾才換行。
  • if 規則只決定輸出內容,不應打亂走格子的次序。
  • 錯誤多數出在輸出格式(空格/換行)或條件判斷寫錯。

小測:換行放在哪裡?

(載入中…)



      
    

五、二維資料掃描:把表格資料逐格處理

重點

  • 二維資料(例如成績表、棋盤)可以用「列×欄」表示,並以 arr[row][col] 存取。
  • 嵌套循環是最自然的逐格掃描方式:外層走 row,內層走 col。
  • 典型任務:加總、計數、搜尋、找最大/最小、檢查是否符合條件。
  • 除錯時先確認 row/col 是否寫反,range 的上界是否正確。

嵌套循環不只用來「印圖案」,更常用來處理表格資料。當你面對二維資料題目時,第一步通常是把資料讀入成一張表;第二步就是用嵌套循環逐格掃描。

在逐格掃描時,請把「內層本體」視為你的工作區:你要加總、計數、或判斷某條件,都放在內層。外層與內層的責任仍然不變:外層帶你走到下一行,內層帶你走過該行所有欄位。

下面的互動示範提供一張固定的 2×3 表格。你可以按「下一步」看到掃描次序,同時看見加總如何累積;亦可以切換到搜尋模式,看見找到目標時如何停止。

狀態

目前 (row, col)
目前值
累計 total
0
按「建立表格」開始。

Python 小練習:加總與搜尋

練習 S3-1:讀入 rows、cols 及表格內容,輸出總和

練習 S3-2:搜尋 target(找到輸出 FOUND,否則輸出 NOT FOUND)

Check Point 4:二維掃描與索引

重點

  • 一般 list-of-lists 用 arr[row][col],先列後欄。
  • 嵌套循環逐格掃描,內層放「處理該格」的程式碼。
  • 索引範圍常由 0 開始:row=0..rows-1,col=0..cols-1。

小測:二維掃描

(載入中…)



      
    

六、縮排的重要性:嵌套循環最常見的除錯關卡

重點

  • 在 Python 中,縮排是語法的一部分:它定義程式區塊,不只是美觀。
  • 嵌套循環的縮排決定「哪一句在外層」「哪一句在內層」,一縮錯就會改變執行次數與輸出格式。
  • 常見錯誤:換行 print() 放錯層、內層計數器重置放錯層、更新變量放錯層造成無限循環。
  • 除錯策略:先用小輸入測試,再暫時印出 row/col 驗證走格子次序。

在嵌套循環中,縮排不只是「排版」,而是「結構」。你可以把縮排看成括號:同一縮排層就像同一對括號內的語句。

很多同學明明懂 for/while 的概念,卻在輸出題中失分,原因往往是把某句放錯層。最典型是換行:它只應該在完成一整行後出現,否則輸出會「散開」。

下面的互動示範讓你一鍵切換「正確縮排」與「錯誤縮排」,並即時看到輸出有何差別。之後你會做 3 題除錯練習,專門訓練你快速判斷縮排層次。

程式碼(概念示範)

外層:行 內層:欄 關鍵:換行位置

輸出比較

按「播放」後,下方會顯示輸出結果。

觀察重點:錯誤縮排不是「少了幾個空格」那麼簡單,而是把換行放進了內層,令每個字元都變成一行。

Python 除錯小練習(縮排導向)

Debug D1:換行縮排錯(修正後應輸出 3 行,每行 4 個 *)

Debug D2:col 重置位置錯(提示:每一行開始前都要把 col 變回 0)

Debug D3:加總位置錯(提示:total 只能初始化一次)

Check Point 5:縮排與除錯

重點

  • 縮排在 Python 中是語法,代表區塊。
  • 換行、重置、更新放錯層,會令輸出或次數完全改變。
  • 除錯時先用小輸入,再用輸出 row/col 驗證執行次序。

小測:縮排觀念

(載入中…)



      
    

七、20 題除錯挑戰:偽代碼 → Python(每題只修正一行;提示需點按才顯示)

重點

  • 每題會先提供情境/題意(用書面語說清楚要做甚麼),再提供偽代碼與一段有錯的 Python 程式。
  • Python 程式中只有一行會標示為 # BUG(不會在程式碼內直接「提示答案」)。
  • 你的任務是:只修正那一行(或把它移到正確縮排層),令輸出符合題意與偽代碼。
  • 提示已移到題目下方的「提示」摺疊區:請先自行嘗試,必要時才點按展開。
  • 建議:先按 Run 程式 觀察錯誤輸出,再按 核對答案 用隱藏測試檢查。
  • 如核對失敗,可優先檢查:換行位置、內層計數器重設位置、range 上界、row/col 是否寫反、型別是否一致。

以下 20 題已設計為「每題只修正一行」。你可以把它當成模擬考的快速操練:每題先跑一次看錯誤,再用縮排與追蹤思維定位問題。

建議流程: ① 先讀偽代碼(了解要做甚麼) → ② Run 觀察錯誤輸出 → ③ 只找一行最可能有問題的位置(換行/重置/更新) → ④ 修正後再核對答案。
(正在載入挑戰題…)