Skip to content

迴圈:讓電腦當免費勞工

還記得上一個模組結尾,我們看到有人寫了 100 行 input() 被嘲笑,而另一個人用 3 行就搞定的場景嗎?

今天,你就是那個拿著咖啡悠哉的人。

模組一教了你怎麼讓電腦說話、聽話、記東西、做判斷。但有一件事一直困擾著我們:如果同一個動作要做 100 次、1000 次呢?難道真的要複製貼上 100 行一模一樣的程式碼?

當然不是。這就是迴圈(Loop)存在的理由:讓電腦幫你重複做同一件事,不管是 10 次還是 10 萬次。

📷 圖 1:學生罰寫 100 遍對比電腦 for loop 秒殺的四格漫畫(AI 製圖)

📷 圖 1:學生罰寫 100 遍對比電腦 for loop 秒殺的四格漫畫(AI 製圖)

💡 📋 學習目標

看完這一節,希望你將能夠:

  1. 了解什麼是迴圈(Loop),以及它為什麼是程式的基礎工具
  2. 學會用 for i in range(n) 讓電腦重複執行指定次數
  3. 學會 range(start, stop, step) 的完整用法
  4. 用 Trace Table(追蹤表)看清迴圈每一步在做什麼
  5. 解兩道 Judge 題 ٩(ˊᗜˋ*)و

目標列好了。先從最根本的問題開始:為什麼我們需要迴圈?


到目前為止,你寫的每一行程式碼,Python 都只會執行一次。如果你想印 5 次 Hello,你得寫 5 行 print("Hello")。那 100 次呢?來看看這有多痛苦。

為什麼需要迴圈?

想像一個場景:老師罰你抄寫「我不會在上課睡覺」100 遍。

為什麼用這個比喻?因為罰寫跟迴圈做的事情本質上一模一樣:重複同一個動作很多很多次。如果你是手抄的:

我不會在上課睡覺
我不會在上課睡覺
我不會在上課睡覺
...(還有 97 遍)

寫到第 50 遍大概手就廢了吧 ╮(╯∀╰)╭

但如果你會寫程式,這件事就變得超簡單。先來看看「沒有迴圈」的時候你得怎麼寫:

python
print("我不會在上課睡覺")
print("我不會在上課睡覺")
print("我不會在上課睡覺")
# ...再複製貼上 97 行?

「老師,這跟手抄有什麼差別?一樣是複製貼上 100 行啊 Σ(゚Д゚;≡;゚д゚) 」

沒錯!這就是問題所在。沒有迴圈的話,程式只會「由上往下」跑一次,跟影印機差不多。但有了迴圈,你可以告訴電腦:「這個動作,給我重複做 N 次。」只要 3 行,搞定。

接下來就讓我們學第一種迴圈:for 迴圈。


你已經知道為什麼需要迴圈了:因為重複的事情太多,手動寫太痛苦。接下來的問題是:怎麼用 Python 告訴電腦「重複做某件事」?答案就是 for 迴圈。

for 迴圈:指定次數的重複

第一個 for 迴圈

回到罰寫的比喻。你可以把 for 迴圈想成一台「自動罰寫機」:你設定次數,它幫你印。

來看看實際的 Python 程式碼長什麼樣:

python
for i in range(5):
    print("我不會在上課睡覺")

按下執行,螢幕上會出現:

我不會在上課睡覺
我不會在上課睡覺
我不會在上課睡覺
我不會在上課睡覺
我不會在上課睡覺

兩行程式碼,搞定 5 遍罰寫。如果改成 range(100),就是 100 遍。兩行。

讓我們拆解這兩行在做什麼:

  1. for i in range(5): — 「從 0 到 4,每次把當前的數字存進 i,然後執行冒號下面的程式碼」
  2. print("我不會在上課睡覺") — 這就是每次迴圈要做的事(迴圈主體)

「等等,你說從 0 到 4?不是 1 到 5 嗎?」

好問題。range(5) 產生的是 0, 1, 2, 3, 4,總共 5 個數字,但從 0 開始、不包含 5。這是 Python 的設計,一開始可能覺得怪,但其實背後有三個很實用的好處——稍後在「常見錯誤:差一錯誤」那一段會詳細解釋。

⚠️ `range(5)` 不包含 5!

range(5) 產生 0, 1, 2, 3, 4,不包含 5。如果你想要 1 到 5,得寫 range(1, 6)(下一段會教)。

i 到底在幹嘛?它是一個變數,每次迴圈會自動更新。來看看一個能看到 i 值的範例:

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

輸出:

0
1
2
3
4

看到了嗎?i 從 0 開始,每次加 1,一直到 4 為止。這就是 range(5) 的效果。

Trace Table:看清每一步

迴圈的程式碼只寫一次,卻會執行好幾次。這代表光看程式碼,你沒辦法「一眼看出」每次執行的狀態。所以我們需要一個工具來「展開」迴圈的每一步。

這個工具叫做 Trace Table(追蹤表)。以 for i in range(5): print(i) 為例:

第幾次i 的值執行內容輸出
10print(0)0
21print(1)1
32print(2)2
43print(3)3
54print(4)4

每一行代表迴圈的一次「輪轉」。i 每次自動加 1,直到達到 range(5) 的上限(5)就停下來。

📌 建議

每次碰到新的迴圈,試著自己畫一張 Trace Table。這是理解迴圈的最好方式,比「在腦中跑程式」準確一百倍。

再看一個稍微複雜的例子:把 i 拿來做計算:

python
for i in range(4):
    print(i * 2)

Trace Table:

第幾次i 的值執行內容輸出
10print(0 * 2)0
21print(1 * 2)2
32print(2 * 2)4
43print(3 * 2)6

看到了嗎?i 不只是一個計數器,它是一個「每次迴圈都會改變的變數」,你可以拿它做任何運算。

縮排的意義

你有注意到 print(...) 前面有空白嗎?那不是裝飾,是 Python 的命脈。

python
for i in range(3):
    print("在迴圈裡面")  # ← 有縮排:屬於迴圈主體
print("在迴圈外面")      # ← 沒縮排:迴圈結束後才執行

輸出:

在迴圈裡面
在迴圈裡面
在迴圈裡面
在迴圈外面

print("在迴圈裡面") 因為有縮排,所以重複了 3 次。print("在迴圈外面") 沒有縮排,所以只印 1 次。

⚠️ 縮排是 Python 的靈魂

Python 用縮排(Indentation)來決定哪些程式碼「屬於迴圈」。如果忘記縮排、或是縮排不一致,Python 會直接報錯:IndentationError

python
for i in range(3):
print("錯了")  # ❌ IndentationError:缺少縮排

一般用 4 個空格做一層縮排(大部分編輯器按 Tab 會自動幫你轉成 4 個空格)。

還記得 1-3 學 if-elif-else 的時候嗎?那時也是用縮排來標記哪些程式碼「屬於某個條件」。迴圈的縮排是同一個道理。

📷 圖 2:縮排決定誰在迴圈裡面的概念圖(AI 製圖)

📷 圖 2:縮排決定誰在迴圈裡面的概念圖(AI 製圖)

⚠️ 別忘了冒號!

for i in range(5): 結尾的冒號(:)是必要的。少了冒號,Python 會報 SyntaxError

python
for i in range(5)   # ❌ SyntaxError:少了冒號
    print(i)

好了,語法搞定了。接下來用一道 Judge 題來驗收你的 for 迴圈功力!

Judge 解題實戰:數字累加器

「老師,剛剛的罰寫例子太簡單了吧 ( ˘•ω•˘ ) 」

來個有挑戰性的。這次你得讓電腦幫你「算數學」:

題目說明

  • Input:一行輸入,一個正整數 N
  • Output:輸出 1 + 2 + 3 + ... + N 的結果

範例

InputOutput
515
1055

老師的建議

先試著自己寫寫看!提示:你需要一個變數來「累加」每次迴圈的結果。

若真的卡關太久,再往下看詳解吧!

先用 IPO 拆解:

Step 1:分析 IPO

  • I(Input):讀取一個正整數 N
  • P(Process):把 1 到 N 的每個數字加起來
  • O(Output):印出總和

「加起來」就是重複做「把當前數字加到一個累加器裡」。完美的 for 迴圈場景!

Step 2:寫出程式碼

根據上面的分析,程式碼可以這樣寫:

python
# I:讀取輸入
n = int(input())

# P:用迴圈累加
total = 0
for i in range(1, n + 1):
    total = total + i

# O:印出結果
print(total)

讓我們逐行解讀:

  1. n = int(input()) — 讀一行輸入,轉成整數,存進 n
  2. total = 0 — 建立一個「累加器」變數,初始值為 0
  3. for i in range(1, n + 1): — 讓 i 從 1 跑到 n(注意 range 不包含結尾,所以要寫 n + 1
  4. total = total + i — 每次迴圈,把當前的 i 加到 total
  5. print(total) — 迴圈結束後,印出最終結果

以 N = 5 為例,Trace Table 長這樣:

第幾次itotal(執行前)執行 total = total + itotal(執行後)
1100 + 11
2211 + 23
3333 + 36
4466 + 410
551010 + 515

迴圈結束,total = 15,印出 15。AC!

📌 `range(1, n + 1)` 是什麼?

你可能注意到這裡用了 range(1, n + 1) 而不是 range(n)。因為 range(n) 是從 0 到 n-1,但我們要從 1 加到 n。range(1, n + 1) 的意思是「從 1 開始,到 n + 1 之前停下」,也就是 1, 2, 3, ..., n。別擔心,下一段會完整教這個語法。

Step 3:在 Judge 上測試

把程式碼貼進 Judge,按下提交。看到 AC 就代表你成功了!

常見錯誤排查

  • range(n) 而不是 range(1, n + 1)

    python
    for i in range(n):  # i 從 0 開始,0+1+2+...+(n-1) 不是我們要的

    range(n) 從 0 開始,少加了 n,多加了 0。結果會比正確答案少 n。

  • 忘記初始化 total = 0

    如果沒有先設 total = 0,Python 會說 NameError: name 'total' is not defined,因為它不知道 total 是什麼。

自己動手試試!

一題搞定了?很好,再來兩題 ✧。٩(ˊᗜˋ)و✧*。

重複問候

問題情境:小琳是學校迎新活動的小幫手,負責在活動開始前用電腦向每位新生送出個人化的歡迎訊息。今年的新生超過三百人,活動組長要求每位新生都要收到一封包含自己名字的歡迎信,而且每封信裡的問候語要重複好幾行才顯得隆重。小琳一開始試著手動複製貼上,結果光是前五位新生就花了快十分鐘,還不小心把名字貼錯了兩次。她心想:如果能寫一個程式,只要輸入新生的名字和想要的歡迎次數,程式就自動幫她印出指定行數的問候語,那該有多省事!這個程式只需要兩個輸入:名字和重複次數,然後把「Hello, 名字」這句話印 N 遍就完成了。

🔍 思考引導

💭 如果用數學來表達...

重複 N 次,就像是「計數器從 1 數到 N,每數一個就印一行」。

第 k 次輸出=Hello, name(k=1,2,,N)

其中 k 是目前的計數,N 是總重複次數。

問題來了:你要怎麼讓迴圈「恰好數 N 次」呢?

🔀 試著補完這張流程圖...

下面的流程圖有些步驟被 ??? 遮住了,試著想想看遮住的地方應該填什麼:

輸入格式: 第一行:名字字串(不含空格) 第二行:正整數 N(1 ≤ N ≤ 100)

輸出格式: 共 N 行,每行格式為 Hello, 名字

範例一

輸入輸出
Alice
3
Hello, Alice
Hello, Alice
Hello, Alice

範例二

輸入輸出
Bob
1
Hello, Bob

範例說明

  • 第一步:讀入 name = Alice,N = 3
  • 第二步:迴圈第 1 次,印出 Hello, Alice
  • 第三步:迴圈第 2 次,印出 Hello, Alice
  • 第四步:迴圈第 3 次,印出 Hello, Alice
  • 第五步:迴圈結束(共印了 3 行)

老師的提示

先想清楚「迴圈要跑幾次」,再決定 range() 的參數。名字要在迴圈之前讀進來,才能在每次迴圈裡使用。


階乘計算機

問題情境:阿豪參加了學校的科學社,社長出了一道題:如果有 N 個人要分組,每個人坐位子的順序都不同算一種排法,總共有幾種排法?阿豪想起數學課學過的排列數公式,答案就是 N 的階乘。可是當人數一多,手算階乘就變得非常痛苦——光是算十個人的排列數就要從一乘到十,中間只要漏乘一個數字或算錯一步,整個結果就全歪了。更糟的是,社長還出了好幾組不同人數的題目要他逐一驗算。阿豪決定寫一個程式來幫忙,只要輸入人數 N,程式就自動把一到 N 的所有整數連乘起來,算出 N 階乘的結果,再也不用擔心手算出錯了。

🔍 思考引導

💭 如果用數學來表達...

階乘的定義是把 1 到 N 的所有整數連乘在一起:

N!=1×2×3××N

可以把它想成一個「乘積累積器」:從 1 出發,每一步把目前的結果再乘以下一個數字。

如果用 Pk 表示乘到第 k 個數字時的結果:

Pk=Pk1×k(k=1,2,,N),P0=1

這跟累加器 Sk=Sk1+k 幾乎一模一樣——差別只在運算符號。那麼,乘積累積器的初始值應該設成多少才不會破壞結果呢?

輸入格式: 第一行:正整數 N(1 ≤ N ≤ 12)

輸出格式: 一行,印出 N! 的值

範例一

輸入輸出
5120

範例二

輸入輸出
11

範例說明

  • 第一步:讀入 N = 5,令乘積累積器 product = 1(初始值)
  • 第二步:k = 1,product = 1 × 1 = 1
  • 第三步:k = 2,product = 1 × 2 = 2
  • 第四步:k = 3,product = 2 × 3 = 6
  • 第五步:k = 4,product = 6 × 4 = 24
  • 第六步:k = 5,product = 24 × 5 = 120
  • 第七步:迴圈結束,印出 120

老師的提示

跟累加器很像,只是把加法換成乘法。關鍵在於:乘積的初始值不能是 0(乘上去全變 0),要想想什麼數字乘上去「不改變結果」。


到這裡,你已經學會了 for i in range(n) 的基本用法。但你有沒有發現一個限制?range(n) 永遠從 0 開始、每次加 1。如果你想從 5 開始呢?想每次加 2 呢?想倒數呢?

接下來就是 range() 的完整版本。

range() 的完整用法

range(start, stop):指定起點

剛才用的 range(5) 其實是偷懶寫法,完整版是 range(0, 5):從 0 開始,到 5 之前停下。

如果你想從 3 開始呢?

python
for i in range(3, 7):
    print(i)

輸出:

3
4
5
6

回到罰寫的比喻:「從第 3 遍開始寫到第 7 遍之前停下」,也就是寫第 3、4、5、6 遍。

`range(start, stop)` 的規則

  • start:起始值(包含)
  • stop:結束值(不包含
  • 所以 range(3, 7) 產生 3, 4, 5, 6,沒有 7

range(start, stop, step):指定步長

如果你想「每次加 2」,產生像 0, 2, 4, 6, 8 這樣的數列呢?第三個參數 step(步長) 就是幹這個的:

python
for i in range(0, 10, 2):
    print(i)

輸出:

0
2
4
6
8

Trace Table:

第幾次i 的值下一步是否 < 10
100 + 2 = 2✅ 繼續
222 + 2 = 4✅ 繼續
344 + 2 = 6✅ 繼續
466 + 2 = 8✅ 繼續
588 + 2 = 10❌ 停止

i 每次加 2,到 10 的時候就停了(因為 range 不包含 stop)。

那如果想倒數呢?step 可以是負數:

python
for i in range(5, 0, -1):
    print(i)

輸出:

5
4
3
2
1

「從 5 開始,每次減 1,到 0 之前停下」。是不是很像倒數計時? (ノ◕ヮ◕)ノ*:・゚✧

📷 圖 3:range 三種用法對比圖(AI 製圖)

📷 圖 3:range 三種用法對比圖(AI 製圖)

range 的三種寫法,其實是同一招

到這裡你已經學了三種 range 的寫法:range(stop)range(start, stop)range(start, stop, step)。看起來像三個不同的工具,其實它們做的事一模一樣——產生一串數字——只是參數越多、你能控制的細節越多。

換個角度看:Python 提供三種便利寫法,對應三種常見場景,讓你不用每次都把所有參數打全。

場景 A:只關心「從 0 跑幾次」

最常見的需求就是「從 0 開始跑 N 次」。這時候只給一個 stop 就好:

python
range(5)       # 從 0 開始、每次加 1、跑到 5 之前 → 0, 1, 2, 3, 4

start 跟 step 都不用寫,Python 會用最常見的設定:start = 0、step = 1。

場景 B:起點不是 0

如果你想從 3 開始算,但每次還是加 1,就把 start 跟 stop 都填進去:

python
range(3, 7)    # 從 3 開始、每次加 1、跑到 7 之前 → 3, 4, 5, 6

step 不寫,Python 一樣會用 1。

場景 C:步長不是 1(要跳格、要倒數)

當你需要「每次加 2」「每次減 1」這類步長時,就把三個參數都填進去:

python
range(0, 10, 2)   # 從 0 開始、每次加 2、跑到 10 之前 → 0, 2, 4, 6, 8
range(5, 0, -1)   # 從 5 開始、每次減 1、跑到 0 之前 → 5, 4, 3, 2, 1

整理一下三種寫法對應到的三種場景:

range(stop)                ← shortest:start = 0、step = 1,從 0 開始跑

       │ 想換起點?

range(start, stop)         ← with start:start 自訂,step 仍然 = 1

       │ 想換步長?

range(start, stop, step)   ← with step:start、step 都自訂

從上往下看,是「能控制的細節越來越多」;從下往上看,是「越來越精簡」。三種寫法的本質一樣,都是 Python 的 range,只是給你選不同精細度的入口 ᕦ(ò_óˇ)ᕤ

順著這個思路,你可能已經注意到 range 產生的數列有一個熟悉的規律:

📌 數學小彩蛋

仔細看 range(0, 10, 2) 產生的 0, 2, 4, 6, 8,有沒有覺得很眼熟?

沒錯,這就是數學課的等差數列:首項 0、公差 2。

事實上,Python 官方文件就是這樣定義 range 的:"It generates arithmetic progressions."(它會產生等差數列。)

start 就是首項 a₁,step 就是公差 d。下次數學課碰到等差數列,你可以偷偷用 Python 驗算 (´∀`)

常見錯誤:差一錯誤

range() 最容易犯的錯,就是所謂的 Off-by-One Error(差一錯誤)

⚠️ 為什麼 `range(1, 5)` 只到 4?

因為 range(start, stop) 的 stop 是不包含的。這是 Python 的設計哲學:

  • range(5) → 5 個數字(0, 1, 2, 3, 4)
  • range(1, 5) → 4 個數字(1, 2, 3, 4)
  • range(1, 6) → 5 個數字(1, 2, 3, 4, 5)

記住口訣:「包頭不包尾」。開頭的數字包含在內,結尾的數字不包含。

📌 為什麼要「包頭不包尾」?三個實用好處

「為什麼 Python 偏偏要設計成『包頭不包尾』,而不是大家直覺的『首尾都包含』?」這不是隨便挑的,背後有三個很實用的設計理由:

  1. 長度好算range(a, b) 裡面有幾個數字?答案就是 b - a,直接相減。例如 range(1, 7)7 - 1 = 6 個數字(1, 2, 3, 4, 5, 6),不用加減 1,超直覺。
  2. 空集合好表達range(5, 5) 代表「沒有任何數字」,自然又乾脆。如果是「首尾都包含」的設計,要表達「空」就得寫 range(5, 4) 之類的反向區間,超怪。
  3. 可乾淨切分:要把 range(0, 10) 切成兩半,可以寫 range(0, 5)range(5, 10),分界點 5 不會重複也不會漏掉。這個性質以後學排序、二分搜尋等演算法時會大派用場。

所以「包頭不包尾」不是 Python 想為難你,而是一個經過深思熟慮的設計。電腦科學家 Edsger W. Dijkstra 在 1982 年寫過一篇手稿〈Why Numbering Should Start at Zero〉就詳細討論過這件事 (•̀ᴗ•́)و

另一個常見的坑:

⚠️ step 為 0 會爆炸

python
for i in range(1, 10, 0):  # ❌ ValueError: range() arg 3 must not be zero
    print(i)

step 不能是 0,因為每次都加 0 就永遠不會前進,Python 會直接報錯。

Judge 解題實戰:倒數計時器

學完了 range() 的三個參數,來做一道倒數題:

題目說明

  • Input:一行輸入,一個正整數 N
  • Output:從 N 倒數到 1(每行一個數字),最後印出 Go!

範例

InputOutput
33
2
1
Go!

老師的建議

先試著自己完成!提示:用 range() 搭配負步長。

卡關了再看解答!

Step 1:分析 IPO

  • I(Input):讀取一個正整數 N
  • P(Process):從 N 倒數到 1
  • O(Output):每個數字印一行,最後印 Go!

Step 2:寫出程式碼

倒數 + 最後喊一聲 Go!,程式碼長這樣:

python
# I:讀取輸入
n = int(input())

# P + O:倒數印出
for i in range(n, 0, -1):
    print(i)

print("Go!")

逐行解讀:

  1. n = int(input()) — 讀取正整數 N
  2. for i in range(n, 0, -1): — 從 n 開始,每次減 1,到 0 之前停下(也就是 n, n-1, ..., 2, 1)
  3. print(i) — 印出當前的數字
  4. print("Go!") — 迴圈結束後才執行(沒有縮排,不屬於迴圈主體)

以 N = 3 為例的 Trace Table:

第幾次i輸出
133
222
311

迴圈結束,印出 Go!

Step 3:在 Judge 上測試

提交看看,應該直接 AC。

常見錯誤排查

  • range(n, 0, -1) 寫成 range(n, 1, -1)

    這樣會漏掉 1,只印到 2。記住「包頭不包尾」:stop 是 0,所以最後一個值是 1。

  • print("Go!") 放在迴圈裡面(有縮排)

    python
    for i in range(n, 0, -1):
        print(i)
        print("Go!")  # ❌ 每次迴圈都會印 Go!

    要確認 print("Go!") 沒有縮排,才會在迴圈結束後只印一次。

自己動手試試!

再來兩題收尾 ᕦ(ò_óˇ)ᕤ

奇數列印機

問題情境:小穎的數學老師在課堂上介紹等差數列,出了一道課堂練習:「請列出一到 N 之間的所有奇數。」班上同學紛紛拿起筆開始一個一個慢慢篩,先看這個數能不能被二整除,不行就寫下來,能的話就跳過。小穎覺得這種做法太沒效率了,尤其當 N 很大的時候,光是判斷和抄寫就要花好久。她仔細觀察之後發現奇數之間藏著一個漂亮的規律:每兩個相鄰奇數之間恰好差二,所以根本不需要逐一檢查,只要從 1 開始、每次加 2 就能直接產生所有奇數。她決定用程式來實現這個想法,輸入 N 之後自動印出所有奇數,由小到大排列,每個數字佔一行。

🔍 思考引導

💭 如果用數學來表達...

奇數其實是一個等差數列:1, 3, 5, 7, 9, ...

k 個奇數可以用公式表示:

ak=2k1(k=1,2,3,)

這個數列的首項是 1,公差是 2。換句話說,從 1 開始,每次加 2,就能產生所有奇數。

你知道 range() 的第三個參數是步長嗎?如果步長設成 2,起點設成 1,能產生什麼樣的數列呢?

輸入格式: 第一行:正整數 N(1 ≤ N ≤ 100)

輸出格式: 從小到大印出所有 1 到 N 之間的奇數(包含 1,若 N 為奇數則包含 N),每個數字獨立一行

範例一

輸入輸出
71
3
5
7

範例二

輸入輸出
11

範例說明

  • 第一步:讀入 N = 7
  • 第二步:從 1 開始,每次加 2,產生數列:1, 3, 5, 7
  • 第三步:印出 1(第 1 個奇數,2×11=1
  • 第四步:印出 3(第 2 個奇數,2×21=3
  • 第五步:印出 5(第 3 個奇數,2×31=5
  • 第六步:印出 7(第 4 個奇數,2×41=7
  • 第七步:下一個是 9,超過 N = 7,停止

老師的提示

奇數數列從 1 開始,公差是 2,所以 range() 的三個參數分別對應首項、上限(注意包頭不包尾)、公差。思考一下 stop 要設多少才能確保 N 本身(若為奇數)也被包含進去。


區間累加器

問題情境:阿軒從國中開始就養成記帳的習慣,每個月會把零用錢的金額記在筆記本上。他發現自己的零用錢是逐月遞增的——從第 A 個月的 A 元開始,每個月多一元,一直到第 B 個月的 B 元為止。到了學期末,阿軒想算一算這段時間自己到底總共存了多少錢,好決定要不要買一直想要的藍牙耳機。如果用手算,他得把 A 到 B 之間的每一個數字逐一加起來,月份一多就很容易漏加或算錯。阿軒心想:何不寫一個程式,只要輸入起始月份 A 和結束月份 B,程式就自動幫他把這個區間內所有整數加總,馬上得到結果呢?

🔍 思考引導

💭 如果用數學來表達...

這是一個等差數列求和問題,首項是 A,末項是 B,公差為 1,項數為 BA+1

數學公式告訴我們:

S=(A+B)(BA+1)2

你可以先用這個公式驗算答案是否正確。但如果用迴圈來計算,你會從哪裡出發、一路加到哪裡停下呢?range() 的起點和終點應該怎麼設?

輸入格式: 第一行:整數 A(1 ≤ A ≤ 1000) 第二行:整數 B,且 A ≤ B(A ≤ B ≤ 1000)

輸出格式: 一行,印出 A 到 B(含兩端)的整數總和

範例一

輸入輸出
1
10
55

範例二

輸入輸出
5
8
26

範例說明

  • 第一步:讀入 A = 1,B = 10,令 total = 0
  • 第二步:依序累加 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
  • 第三步:total = 0+1=1 → 1+2=3 → 3+3=6 → 6+4=10 → 10+5=15 → 15+6=21 → 21+7=28 → 28+8=36 → 36+9=45 → 45+10=55
  • 第四步:迴圈結束,印出 55

用公式驗算:(1+10)×102=1102=55

老師的提示

跟數字累加器幾乎一模一樣,只是 range() 的起點和終點要換成 A 和 B。記住「包頭不包尾」,stop 要設成 B+1 才能把 B 本身包含進去。

等差數列求和

問題情境:小蕾在數學課學完等差數列之後,老師出了一份驗算作業,上面有好幾組不同的等差數列,每組都給了首項、公差和項數,要求算出所有項的總和。小蕾用公式算了前兩題,發現每次都要先算出末項、再代入求和公式,過程中稍有不慎就會算錯,尤其公差比較大或項數比較多的時候,光是展開數列就寫滿了半張紙。她突然想到剛學的 Python 迴圈和 range() 函式,如果把首項當起點、公差當步長,不就能直接產生整個等差數列嗎?再搭配累加器逐項加總,答案立刻就出來了。她決定寫一個程式,只要輸入首項、公差和項數,電腦就自動幫她把所有項加起來,省下大量手算的時間。

🔍 思考引導

💭 如果用數學來表達...

等差數列的各項為 a, a+d, a+2d, , a+(n1)d,共 n 項,總和公式為:

S=na+n(n1)2d

你可以用這個公式來驗算結果是否正確。但若改用迴圈來計算,range(a, a + d*n, d) 正好會產生這 n 個項——首項是 a,每次加 d,在 a+d×n 之前停下(共 n 項)。

試著追蹤看看:a=1, d=2, n=5 時,range(1, 11, 2) 會產生哪些數字?

輸入格式: 第一行:首項 a(-100 ≤ a ≤ 100) 第二行:公差 d(1 ≤ d ≤ 50) 第三行:項數 n(1 ≤ n ≤ 100)

輸出格式: 一行,印出所有項的總和

範例一

輸入輸出
1
2
5
25

範例二

輸入輸出
10
5
4
70

範例說明

  • 第一步:讀入 a = 1,d = 2,n = 5,令 total = 0
  • 第二步:range(1, 1 + 2×5, 2) = range(1, 11, 2) 產生數列:1, 3, 5, 7, 9
  • 第三步:迴圈第 1 次,項值 = 1,total = 0 + 1 = 1
  • 第四步:迴圈第 2 次,項值 = 3,total = 1 + 3 = 4
  • 第五步:迴圈第 3 次,項值 = 5,total = 4 + 5 = 9
  • 第六步:迴圈第 4 次,項值 = 7,total = 9 + 7 = 16
  • 第七步:迴圈第 5 次,項值 = 9,total = 16 + 9 = 25
  • 第八步:迴圈結束,印出 25

用公式驗算:S=5×1+5×42×2=5+20=25

老師的提示

range(a, a + d * n, d) 可以直接產生整個等差數列,不需要自己計算每一項。思考一下為什麼 stop 是 a + d * n 而不是 a + d * (n-1)——包頭不包尾的規則在這裡同樣適用。


數字階梯

問題情境:阿志在資訊社的社課上遇到一個練習題,社長要大家用程式印出一個「數字階梯」——從一開始,依序把每個數字印在獨立的一行,一直印到 N 為止。阿志一開始覺得很簡單,直接用好幾行 print 硬寫,結果社長說 N 是由使用者輸入的,不是固定的數字,所以不可能事先知道要寫幾行。阿志才意識到,這題的重點是讓迴圈根據輸入的 N 來自動決定要印幾行。他只要設定好迴圈的起點和終點,每次迴圈把當前的數字印出來,就能完成這個看似簡單卻很實用的小程式了。

🔍 思考引導

🧩 把大問題拆成小問題...

  1. 第一步 — 理解規律:仔細看輸出,第 i 行印的就是數字 i。你能描述這個規律嗎?
  2. 第二步 — 設定迴圈範圍:迴圈要從幾跑到幾?起點和終點分別是什麼?
  3. 第三步 — ???:每次迴圈執行一次,你要用 print 印出什麼?

輸入格式: 第一行:一個正整數 N(1 ≤ N ≤ 50)

輸出格式: 共 N 行,第 i 行印數字 i

範例一

輸入輸出
41
2
3
4

範例二

輸入輸出
11

範例說明

  • 第一步:讀入 N = 4
  • 第二步:迴圈 i = 1,印出 1
  • 第三步:迴圈 i = 2,印出 2
  • 第四步:迴圈 i = 3,印出 3
  • 第五步:迴圈 i = 4,印出 4
  • 第六步:迴圈結束(共印了 4 行,與 N = 4 一致)

老師的提示

只需要一個 for 迴圈,讓迴圈變數 i 恰好從 1 跑到 N(含 N)。range(1, n+1) 可以做到這件事——想一想為什麼 stop 要是 n+1 而不是 n


星星正方形

問題情境:小潔在學校電腦課被要求用程式印出一個「星星正方形」——輸入邊長 N,程式要印出 N 行,每行恰好有 N 個星號,形成一個整齊的正方形圖案。小潔一開始想用手動的方式,針對不同的 N 各寫一組 print,但馬上就發現行不通:N 是使用者輸入的,沒辦法事先知道要印幾行、每行幾個星號。她仔細觀察範例輸出之後,注意到一個漂亮的規律——每一行的內容完全相同,都是 N 個星號連在一起,所以只要想辦法讓程式重複印出同樣的那一行共 N 次,整個正方形就完成了。這讓她想起剛學的字串乘法和迴圈,兩個工具搭配起來就能漂亮地解決這個問題。

🔍 思考引導

🧩 把大問題拆成小問題...

  1. 第一步 — 搞清楚每行要印什麼:輸出的每一行都是 N 個 * 連在一起,例如 N=3 時每行是 ***。在 Python 裡,"*" * N 就能產生這個字串,你試試看。
  2. 第二步 — 決定要印幾行:總共需要印 N 行,也就是迴圈要跑 N 次。
  3. 第三步 — ???:每次迴圈,你要把第一步的字串印出來。迴圈變數本身在這題用不到,你能想到怎麼寫嗎?

輸入格式: 第一行:一個正整數 N(1 ≤ N ≤ 20)

輸出格式: 共 N 行,每行恰好 N 個 *

範例一

輸入輸出
3***
***
***

範例二

輸入輸出
5*****
*****
*****
*****
*****

範例說明

  • 第一步:讀入 N = 3
  • 第二步:每行要印的字串是 "*" * 3 = "***"
  • 第三步:迴圈第 1 次,印出 ***
  • 第四步:迴圈第 2 次,印出 ***
  • 第五步:迴圈第 3 次,印出 ***
  • 第六步:迴圈結束(共印了 3 行,形成 3×3 的星星正方形)

老師的提示

"*" * n 能直接建出一整行的星號字串,不需要內層迴圈。外層迴圈只負責控制「要印幾行」,每次迴圈的工作就是 print("*" * n),簡單俐落。


倒數偶數

問題情境:阿廷是班上的體育股長,每次體育課開始前都要帶全班做暖身操。他喊口號的方式比較特別:從一個偶數 N 開始倒數,每次減二,一直喊到二為止,用來控制暖身動作的節奏。平常都是他自己在操場上喊,但最近學校運動會要預錄一段倒數音檔,需要精確地列出每一個要喊的數字。阿廷覺得手寫容易漏掉或搞錯順序,特別是當起始數字比較大的時候。他想用程式來幫忙,只要輸入起始的偶數 N,程式就自動依序印出 N、N 減二、N 減四一直到二為止,每個數字佔一行,這樣他就能直接把輸出結果交給負責錄音的同學了。

🔍 思考引導

💭 如果用數學來表達...

這個倒數數列是:N, N2, N4, , 4, 2

這是首項 N、公差 2(遞減)的等差數列,共有 N2 項。

k 項的值為:

ak=N2(k1)(k=1,2,,N2)

若用 range() 來產生這個數列,start 是 N、每次減 2(也就是 step = -2)、在哪裡停下才能確保 2 被包含進去?

🔀 試著補完這張流程圖...

下面的流程圖有些步驟被 ??? 遮住了,試著想想看遮住的地方應該填什麼:

輸入格式: 第一行:一個正偶數 N(2 ≤ N ≤ 100)

輸出格式: 從 N 到 2,每次減 2,每個數字獨立一行

範例一

輸入輸出
88
6
4
2

範例二

輸入輸出
22

範例說明

  • 第一步:讀入 N = 8,數列共有 8÷2=4
  • 第二步:迴圈第 1 次,i = 8,印出 8
  • 第三步:迴圈第 2 次,i = 6,印出 6
  • 第四步:迴圈第 3 次,i = 4,印出 4
  • 第五步:迴圈第 4 次,i = 2,印出 2
  • 第六步:下一個是 0,不在範圍內,迴圈結束

老師的提示

range(n, 0, -2) 能產生從 N 倒數、步長為 -2 的序列。記住包頭不包尾:stop 設成 0,最後一個輸出值就是 2。為什麼是 0 而不是 2?因為 2 要「包含進去」,所以 stop 要比 2 再小一步。


到這裡,2-1 的內容就全部結束了。你已經解鎖了第一個迴圈工具!在回顧重點之前,先補一個關於 range 的小冷知識:它跟你以為的可能不太一樣。

📌 `range` 不是一串現成的數字

看到這你可能會想:「range(5) 不就是 0, 1, 2, 3, 4 這串數字嗎?」聽起來很合理,但事情有點不同。試試看:

python
print(range(5))

你以為會看到 0 1 2 3 4,結果螢幕上印的是:

range(0, 5)

……長得跟你寫的程式碼一模一樣 (・∀・)? 這是因為 range(5) 其實是一個「按需要才產生數字」的物件,數字是「用到才算」的,不是事先全部存起來。所以在 for i in range(5) 裡面它會一個一個吐出 0, 1, 2, 3, 4 給你;但如果你只是 print(range(5)),它就只把自己的長相印給你看。

想看完整的數字清單怎麼辦?可以套一層 list()

python
print(list(range(5)))

輸出:

[0, 1, 2, 3, 4]

list 跟中括號 [ ] 是後面才會學的「串列」概念,這裡先當作小知識,知道有這招就好。)

OK,回顧時間到。

本節小結

🎯 重點回顧:

  • 迴圈(Loop) 讓電腦重複執行同一段程式碼,解決「複製貼上一百遍」的問題
  • for i in range(n)i 從 0 跑到 n-1,共 n 次
  • range(start, stop, step) 可以指定起點、終點和步長,甚至用負步長倒數
  • Trace Table 是理解迴圈的最佳工具:把每次迴圈的變數值攤開來看
  • 縮排 決定哪些程式碼在迴圈裡面、哪些在外面
  • 包頭不包尾range 的 stop 值不包含在內

📝 下一節:「while 條件迴圈」:

for 迴圈適合你「確切知道要跑幾次」的場合。但如果你不知道要跑幾次呢?比方說:「一直問使用者要不要繼續,直到他說不要為止。」這種情況你沒辦法事先知道迴圈要跑幾次,for 就不夠用了。

下一節會教你另一種迴圈:while。它不是「跑 N 次」,而是「跑到條件不成立為止」。聽起來更自由,但也更容易出事⋯⋯(劇透:無窮迴圈 ∞ )