Day 5 迴圈入門
引言
昨天的內容中,我們用條件判斷讓程式可以根據情況做出不同反應。不過,如果要重複執行某段程式碼好幾次(例如把清單裡的每一筆資料都處理過一次),光靠條件判斷就顯得麻煩。迴圈正是用來解決這種「重複」情境的利器,它能讓我們用簡短的程式碼完成大量的重複工作。
這篇文章會帶你認識 Python 的兩大迴圈:for 與 while。for 適合用於「已知要走訪幾次」或「要逐筆處理容器」的情境,while 則適合用在「只要條件成立就一直做下去」的情境。我們也會介紹 range() 函式、break 與 continue 這兩個控制流程的關鍵字,幫助你寫出更具彈性的迴圈。
for 迴圈與 range()
for 迴圈用來依序走訪一個序列(例如串列、字串、range 物件),每走訪一次就執行縮排內的程式碼。其中最常見的搭配就是內建函式 range(),它會產生一連串的整數,用法有三種:range(stop)、range(start, stop)、range(start, stop, step)。
# 從 0 數到 4
for i in range(5):
print(i)
# 輸出:
# 0
# 1
# 2
# 3
# 4
# 設定起點與終點
for i in range(1, 6):
print(i) # 1, 2, 3, 4, 5
# 設定間隔(step)
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
注意 range(stop) 是「含頭不含尾」,也就是從 0 開始,到 stop - 1 結束。這個設計在處理「前 N 個」、「從 1 到 N-1」這類索引範圍時相當方便。range() 本身並不是串列,但可以透過 list(range(5)) 轉換成串列以便查看內容。
for 迴圈走訪容器
for 迴圈除了搭配 range(),更常見的用法是直接走訪容器中的元素。這個寫法語法簡潔,不需要額外處理索引,是 Python 強調可讀性的特色之一。
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(f"我喜歡吃 {fruit}")
# 走訪字串中的每個字元
for ch in "Python":
print(ch)
執行程式會依序輸出「我喜歡吃 apple」、「我喜歡吃 banana」、「我喜歡吃 cherry」,以及 P、y、t、h、o、n。for 迴圈的變數名稱可以自由命名,重點是要能表達「正在走訪的每一筆資料」。如果迴圈內不需要使用這個變數,習慣上會用 _ 來表示,例如 for _ in range(3):。
while 迴圈
當迴圈次數不固定,而是取決於某個條件時,while 迴圈會比 for 更適合。while 會反覆執行縮排內的程式碼,直到條件變成 False 為止。
count = 1
while count <= 5:
print(count)
count += 1
這段程式會輸出 1 到 5。每次迴圈結束後,count 會加 1,直到 count <= 5 不再成立為止。寫 while 迴圈時,務必確認迴圈內有改變條件的程式碼,否則會陷入無窮迴圈(infinite loop),讓程式永遠停不下來。
一個簡單的判斷方式是:如果迴圈次數可以用 range() 表達,通常用 for;如果次數要看執行時的狀況,則用 while。例如「使用者輸入正確為止」就適合用 while。
break:提前跳出迴圈
有時候我們會在迴圈中間判斷某個條件,一旦符合就想立刻結束整個迴圈,這時候可以用 break。它會中斷最近的迴圈,讓程式直接執行迴圈之後的程式碼。
# 找出第一個大於 50 的數字
numbers = [12, 35, 67, 20, 88, 45]
for n in numbers:
if n > 50:
print(f"找到第一個大於 50 的數字:{n}")
break
執行程式會輸出「找到第一個大於 50 的數字:67」,然後立刻結束迴圈,不會繼續處理後面的 20、88、45。break 在搜尋、驗證輸入、遇到錯誤條件想提早結束等情境非常實用,可以避免不必要的運算。
continue:跳過這一輪
如果只想跳過「這一輪」的程式碼,但還想繼續執行後續的元素,可以使用 continue。它會立刻回到迴圈開頭,重新評估條件並進入下一輪。
# 只印出奇數
for i in range(1, 8):
if i % 2 == 0:
continue
print(i)
輸出結果是 1、3、5、7。遇到偶數時 continue 會跳過 print(),直接進入下一輪。break 與 continue 是控制迴圈流程的兩個重要關鍵字:前者結束整個迴圈,後者只跳過這一輪。
迴圈的 else 子句
Python 的迴圈有個特殊的設計:可以在 for 或 while 後面加上一個 else 區塊。這個 else 只會在「迴圈正常跑完所有元素」時執行;如果是用 break 中途跳出,else 區塊則不會執行。這個特性在搜尋類情境特別好用,可以用來區分「有找到」與「沒找到」兩種情況。
# 找出串列中是否有目標值
target = 42
numbers = [10, 20, 30, 40, 50]
for n in numbers:
if n == target:
print("找到了")
break
else:
print("找不到") # 因為沒 break,會執行這裡
執行程式會輸出「找不到」。如果把 target 改成 30,則會輸出「找到了」,而且 else 區塊不會執行。這個寫法比手動額外設一個布林旗標更直覺,也是 Python 社群中相當推薦的慣用模式。
實用範例:累計與計數
迴圈最常見的應用之一是「累計」與「計數」。把一個變數初始化為 0,然後在迴圈內根據條件累加,就能快速算出總和、計數或平均等統計資料。
# 計算 1 到 100 的總和
total = 0
for i in range(1, 101):
total += i
print(total) # 輸出 5050
# 統計串列中偶數的個數
nums = [12, 7, 33, 8, 21, 50, 4]
even_count = 0
for n in nums:
if n % 2 == 0:
even_count += 1
print(even_count) # 輸出 4
這種「先初始化、再迭代累加」的模式非常普遍。事實上,Python 內建的 sum() 函式已經幫我們處理了這個流程,因此實務上 print(sum(range(1, 101))) 就能直接得到 5050。不過,了解背後原理仍然是寫程式的重要基礎。
另一個常見的延伸是計算平均值:先把總和算出來,再除以個數。Python 提供了 len() 來取得串列長度,搭配 sum() 就能一行寫出平均。
scores = [78, 92, 65, 88, 73]
average = sum(scores) / len(scores)
print(average) # 輸出 79.2
迴圈常見錯誤
撰寫迴圈時,有幾個常見的錯誤值得特別留意。
無窮迴圈:這是 while 最常見的陷阱。若迴圈內忘了更新會改變條件的變數(例如忘了寫 count += 1),條件會永遠成立,導致程式跑不停。遇到這種情況,可以按 Ctrl + C 中斷程式。
# 錯誤示範:忘記更新 count
count = 1
while count <= 5:
print(count)
# 忘了寫 count += 1,會一直印 1
縮排錯誤:迴圈內的程式碼如果縮排不一致(有些用 2 個空格、有些用 4 個空格),Python 會直接報 IndentationError。建議統一使用 4 個半形空格,並讓編輯器把 Tab 自動轉成空格。
把 while True: 當萬用解:有些初學者會把所有 while 迴圈都寫成 while True: 再用 break 結束。雖然可行,但在條件可以預先寫清楚時,直接寫條件會讓程式碼更容易閱讀。
實用範例:簡易使用者驗證
把迴圈、條件判斷與字串處理結合,我們寫一個「密碼錯誤就重新輸入」的小範例。這個情境在真實應用中很常見,例如登入介面、ATM、或設定選單。
correct_password = "python123"
while True:
password = input("請輸入密碼:")
if password == correct_password:
print("登入成功!")
break
else:
print("密碼錯誤,請再試一次")
這段程式展示了典型的「使用者互動迴圈」:不知道使用者會試幾次,所以用 while True 持續詢問,直到條件成立才用 break 結束。實務上通常會再限制「最多嘗試 3 次」或加上「嘗試間隔」,以避免無限制的重試。
迴圈與其他語法的搭配
迴圈經常會與其他語法一起出現,了解它們的搭配方式能讓你寫出更精簡的程式碼。
迴圈 + 串列推導式:昨天還沒學到推導式(會在 Day 10 介紹),但可以先預告一個常見寫法——把「建立新串列」與「走訪舊串列」合併成一行:
# 等同 [0, 2, 4, 6, 8]
evens = [i for i in range(10) if i % 2 == 0]
print(evens)
迴圈 + 函式:當迴圈內的邏輯變得複雜時,可以把它抽成函式,再由迴圈呼叫。這樣做不只讓主迴圈更短,也方便測試與重用。
這些組合都會在後續章節深入介紹,現在只要有個印象即可。
結語
今天我們認識了 Python 的兩大迴圈:for 與 while。for 適合用於已知次數或走訪容器的情境,while 則適合條件驅動的迴圈。我們也學會了 range() 的三種用法,以及用 break 提前跳出迴圈、用 continue 跳過這一輪。掌握這些之後,你已經能用簡短的程式碼處理大量重複的工作。
明天,我們會進一步探討迴圈的進階用法,包括巢狀迴圈、else 子句的妙用,並用九九乘法表和猜數字遊戲做綜合練習,把今天學到的技巧應用到更貼近真實的場景中。
留言
張貼留言