主題: 學習筆記
Python 電腦科學與程式設計導論 第三講:迭代
MIT OpenCourseWare 6.100L 第三講筆記:while、for、range、流程控制、近似法與迭代模式。
迭代(iteration)很像把你的意圖塞進一台節拍器:只要條件成立,或只要還有下一個元素,就繼續敲。MIT 6.100L Lecture 3 用幾個非常「人類」的例子,把 while 與 for 的直覺釘進腦內:迷失森林、Netflix 追劇、階乘、running sum。這篇文章把它們整理成可操作的心智模型,再加上一點「工程師的防呆習慣」。
學迴圈的最短路徑
不要背語法。先問一句:「我到底是在等一個條件變化?」 還是 「我是在走訪一個序列?」
前者幾乎都用
while;後者幾乎都用for。
1) while:條件為王,但也最容易召喚黑洞
while 的語意很純粹:
只要條件為 True,就執行區塊;每次執行完再回去檢查一次。
所以它非常適合「你不知道要重複幾次」的任務:等待使用者輸入正確格式、等待某個狀態改變、等待資料到齊……(也因此最容易寫出「永遠等不到明天」的無窮迴圈)。
迷失森林的 Python 版本(含大小寫防呆)
where = input("Go left or right? ")
# 先把輸入轉小寫,避免 RIGHT / Right 造成語意偏差
where = where.strip().lower()
while where == "right":
where = input("Go left or right? ").strip().lower()
print("You got out of the Lost Forest!")
注意:無窮迴圈的兩種死法(都很常見)
- 條件永遠不會變:你在迴圈裡沒有更新跟條件相關的變數。
- 條件其實會變,但你沒察覺:例如大小寫、空白、型別(字串 vs 數字)讓條件判斷偏掉。
2) Netflix 的「Are you still watching?」其實是一個 while 思想實驗
Lecture 3 用 Netflix 追劇當比喻:只要還有下一集、只要你還在互動,它就繼續播放;如果你睡著或播完了,條件變成 False,迴圈停止,然後丟出提示。
你可以把它想成:
- 狀態:
still_has_episode、user_is_active - 迴圈:只要兩者都成立,就
play_next_episode()
這個例子重要的不是 Netflix,而是你會開始用「狀態 + 條件」思考流程控制。
3) for:優雅地走訪序列(尤其是 range)
當你想做的事其實是「做 N 次」或「走過一段整數範圍」,for 幾乎總是更乾淨:
# while 版本(你要自己維護 n)
n = 0
while n < 5:
print(n)
n += 1
# for 版本(把「n 會怎麼變」交給 range)
for n in range(5):
print(n)
range(start, stop, step):stop 不包含在內,這是設計不是陷阱
你會在很多地方受益:
- 對齊索引:
range(len(arr))產生合法索引 - 避免多印一個:stop 不包含 → 邊界更一致
- 倒著走:
range(4, 0, -1)這種倒數很直覺
筆記:最容易記的規則
range(5)會產生[0,1,2,3,4]。不是 Python 在耍你,是它在幫你:這樣剛好對齊「序列長度為 5 的合法索引」。
4) Running Sum:把「累積」變成一種迴圈肌肉記憶
Running sum(累積總和)是最值得早早練熟的模式之一:你會在統計、資料處理、演算法裡反覆遇到它。
mysum = 0
for i in range(10): # i: 0..9
mysum += i
print(mysum) # 45
小訣竅:腦內配音法(超有效)
每次迭代都用一句話描述狀態: 「現在 i 是多少?mysum 目前是多少?這一輪會加上什麼?」 這其實就是把 Python Tutor 的視覺化搬到你的腦袋裡。
5) 階乘(factorial):while vs for 的可讀性對決
階乘是經典案例:n! = 1 × 2 × ... × n
# while 版本:你要手動推進 i
x = 4
i = 1
factorial = 1
while i <= x:
factorial *= i
i += 1
print(f"{x} factorial is {factorial}")
# for 版本:少了「推進 i」的維護成本
x = 4
factorial = 1
for i in range(1, x + 1):
factorial *= i
print(f"{x} factorial is {factorial}")
筆記:工程視角的結論(務實)
只要你是在走訪一個明確序列(例如 1..n),
for通常更不易出錯;while的強項是「等狀態變化」或「次數未知」。
6) 迴圈控制:break、continue、以及那個看起來像在偷懶的 pass
三個關鍵字,三種不同的「流程手勢」:
break:直接離開迴圈(緊急出口)continue:跳過本輪,直接去下一輪(略過不想處理的情況)pass:什麼都不做(語法占位用)
範例:輸入驗證(含 while-else)
correct_password = "magic123"
attempts = 0
while attempts < 3:
pwd = input("請輸入密碼: ")
if pwd == correct_password:
print("歡迎登入!")
break
else:
print("密碼錯誤,再試一次。")
attempts += 1
else:
# 只有「沒有被 break 打斷」才會跑到這裡
print("多次輸入錯誤,帳號鎖定!")
小訣竅:while-else 其實很優雅
它把「正常跑完」與「中途 break」分流得很乾淨: break = 你提前離席;else = 你把流程走到自然結束。
範例:用 continue 篩選資料(少一層巢狀 if)
numbers = [4, -2, 0, 7, -5, 3]
positives = []
for n in numbers:
if n <= 0:
continue
positives.append(n)
print("正數有:", positives) # [4, 7, 3]
7) Debug 迴圈的三條鐵律(讓你少掉一半痛苦)
- 先寫出「迴圈不變量」:每輪開始時,你希望哪些條件成立?(例如
mysum永遠等於已處理元素的總和) - 檢查邊界(off-by-one):你到底要包含 end 嗎?
range的 stop 不包含在內,這點要非常清楚。 - 需要可視化時,直接上工具:用 Python Tutor 看每一步變數怎麼變,對初學者是降維打擊。
延伸閱讀(精準補強)
-
MIT OCW:Lecture 3: Iteration(頁面與練習入口)
-
MIT OCW:Lecture 3 影片資源頁(含 transcript 下載)
-
YouTube:Lecture 3: Iteration(你提供的連結)
-
Python 官方教學:Control Flow Tools(range / for / while 的語意與例子)
-
Python 官方語言參考:break 的精確語意(含 loop-else 行為細節)
-
Real Python:Python while Loops(更完整的 while 適用情境與陷阱整理)
-
Python Tutor:逐步視覺化執行流程(強烈推薦)