本文 AI 產出,尚未審核

Python 教學:控制流程 – else 在迴圈中的用途


簡介

在 Python 的控制流程裡,for 與 while 迴圈是最常使用的結構。大部分學習者在寫完迴圈後,會直接在外層加上 else,卻不曉得它真正的意義與應用。其實,else 並不是「如果條件不成立」的意思,而是 迴圈正常結束(即沒有被 break 中斷)時才會執行的程式區塊。善用這個特性,可以讓程式碼更具可讀性、減少重複的旗標變數,並在搜尋、驗證或清理資源時提供簡潔的寫法。

本篇文章將深入說明 else 在迴圈中的行為,提供多個實用範例,並討論常見的陷阱與最佳實踐,讓你在日常開發中能夠 寫出更清晰、更安全 的程式。


核心概念

1. else 與 break 的關係

  • 正常結束:迴圈遍歷完所有元素,且 未執行 break,此時會執行 else 區塊。
  • 提前終止:如果迴圈內部執行了 break,else 不會被執行。

小技巧:把需要在「找不到目標」或「全部檢查完」時才執行的程式碼,直接放在 else,即可省去額外的旗標變數。

for n in range(1, 6):
    if n == 10:          # 永遠不會成立
        break
else:                     # 迴圈跑完才會到這裡
    print("迴圈完整執行完畢")

2. while 迴圈的 else

while 迴圈的 else 行為與 for 完全相同,只是條件是「迴圈條件變為 False」時才會執行 else,除非在迴圈內先 break。

i = 0
while i < 3:
    print(i)
    i += 1
else:                     # i == 3 時才會執行
    print("while 正常結束")

3. 為什麼 Python 設計成這樣?

else 在迴圈中的設計來源於 早期的搜尋演算法,例如在列表中找尋特定元素時:

  • 若找到元素,立即 break,結束搜尋。
  • 若遍歷完仍未找到,則在 else 中處理「未找到」的情況。

這樣的語法讓 搜尋與未找到的處理 能寫在同一段程式碼裡,避免了額外的布林旗標或 if-else 巢狀結構。


程式碼範例

以下提供 5 個常見且實用的範例,說明 else 在迴圈中的多種應用。

範例 1:在列表中搜尋指定值

def find_target(seq, target):
    for idx, value in enumerate(seq):
        if value == target:
            print(f"找到目標 {target},位置在 index {idx}")
            break               # 找到後立即離開迴圈
    else:
        # 只會在遍歷完 seq,且沒有 break 時執行
        print(f"目標 {target} 不在序列中")

說明:若 target 不在 seq 中,else 會印出「未找到」的訊息,程式碼不需要額外的 found = False 旗標。


範例 2:驗證所有元素是否符合條件

def all_even(numbers):
    for n in numbers:
        if n % 2 != 0:          # 一旦發現奇數,直接中斷
            print(f"發現奇數 {n},不是全部偶數")
            break
    else:
        # 迴圈走完都沒 break,代表全部都是偶數
        print("所有數字皆為偶數")

說明:else 用來表示「所有檢查都通過」的情況,讓程式的意圖更加直觀。


範例 3:從檔案中讀取資料,直到找到特定標記

def read_until_marker(filepath, marker):
    with open(filepath, "r", encoding="utf-8") as f:
        for line in f:
            if marker in line:
                print("找到標記,停止讀取")
                break
        else:
            # 檔案讀完整個都沒找到標記
            print("檔案結束,仍未發現標記")

說明:使用 else 可以在「找不到標記」時給予使用者明確的回饋,而不必在迴圈外額外檢查 found 變數。


範例 4:while 迴圈的倒數計時

def countdown(seconds):
    while seconds > 0:
        print(seconds)
        seconds -= 1
    else:
        # seconds 變成 0 時會執行
        print("時間到!")

說明:else 在此作為「計時結束」的訊息,讓主流程更清晰。


範例 5:自訂搜尋演算法 – 找出第一個符合條件的素數

def first_prime(limit):
    for n in range(2, limit):
        for i in range(2, int(n**0.5) + 1):
            if n % i == 0:
                break               # n 不是素數,離開內層迴圈
        else:
            # 內層迴圈沒有 break,表示 n 為素數
            print(f"找到素數 {n}")
            return n
    else:
        # 外層迴圈跑完仍未找到素數
        print(f"在 2~{limit-1} 之間找不到素數")
        return None

說明:此範例同時展示 內層 for...else 與 外層 for...else 的用法,說明如何在多層迴圈中利用 else 來判斷「未被 break」的情況。


常見陷阱與最佳實踐

陷阱 說明 建議的做法
把 else 當成 if not 初學者常把 else 誤認為「條件不成立」的分支,結果在 break 時行為不符預期。 記住 else 只在 迴圈未被 break 時執行。必要時在程式碼註解說明。
在 else 裡使用 continue continue 只能在迴圈內部使用,else 已經是迴圈結束的區塊,使用會拋出 SyntaxError。 若需要在「未找到」的情況下重新開始迴圈,請把邏輯寫回迴圈本體或使用 while True。
與 try/except/else 混淆 Python 也支援 try...except...else,但兩者的 else 含義不同,可能造成混淆。 在程式碼註解或文件中明確說明是哪種 else(迴圈 vs 例外處理)。
忘記縮排 else 必須與對應的 for/while 同層縮排,縮排錯誤會導致語法錯誤或行為異常。 使用 IDE 或 linter 自動檢查縮排。
在大量資料搜尋時仍使用 else 雖然 else 能省掉旗標變數,但在搜尋大量資料時,若需要頻繁記錄「未找到」的次數,仍應使用計數器或 any()/all()。 依需求選擇最合適的工具,else 只適合一次性「是否找到」的判斷。

最佳實踐:

  1. 明確註解:在 else 前加上簡短註解,說明「此區塊在迴圈完整執行後才會執行」。
  2. 避免過度巢狀:若需要多層 else,考慮將搜尋邏輯抽成函式,提升可讀性。
  3. 與 any()、all() 搭配:在簡單的「是否全部符合」或「是否至少一個符合」情況,可直接使用內建函式,減少手寫迴圈與 else。
  4. 測試 break 與 else 的互動:寫單元測試時,確保在觸發 break 的情境下 else 不會被執行,避免邏輯漏洞。

實際應用場景

  1. 資料驗證:在批次處理 CSV 時,檢查每一列是否符合格式,若全部符合則寫入資料庫,否則在 else 中記錄錯誤。
  2. 網路爬蟲:遍歷多個 URL,若在任一頁面找到關鍵字即 break,否則在 else 中回報「未找到」。
  3. 遊戲開發:在回合制遊戲中,迴圈檢查玩家是否達成勝利條件,若全部回合都未達成,else 負責觸發平手結局。
  4. 資源清理:使用 while 讀取資料流,若正常結束(流結束),在 else 中釋放資源;若因例外或 break 中斷,則在 except 或 finally 處理。
  5. 演算法實作:在圖形搜尋(BFS/DFS)或排列組合問題中,常用 for...else 判斷「沒有符合條件的鄰居」或「所有路徑都已探索完」的情況。

總結

else 在 Python 迴圈中的設計是一個 語意清晰、降低程式複雜度 的小技巧。透過 else:

  • 可以 省去額外的旗標變數,讓程式更簡潔。
  • 明確表達「迴圈完整執行」或「未被 break 中斷」的意圖。
  • 在搜尋、驗證、資源管理等常見情境中,提供 直觀且易於維護 的寫法。

掌握這個概念後,你的程式碼將更具可讀性,也更不容易因為忘記檢查 break 而產生隱藏錯誤。建議在日常開發中,多練習把 「找不到」或「全部通過」 的邏輯搬到迴圈的 else 區塊,逐步養成 Pythonic 的寫作風格。祝你寫程式愉快,持續進階!