iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0

前言

昨天我們玩了 while 的基本功,知道它就像一個「守門員」:

  • 條件成立 → 就繼續跑
  • 條件不成立 → 就乖乖停下來
  • 條件一開始就不成立 → 甚至一次都不會執行

還搭配了 break 跳出、continue 跳過,
做了幾個超實用的練習(ATM、密碼驗證、清單動態刪除)。

那今天呢?

我們要來看 while 的兩個進階技能

1.無窮迴圈(infinite loop) — while True:
2.while + else — 很多人第一次看到會黑人問號,但其實超有用!

這兩個觀念學會之後,你會對迴圈的「掌控感」再往上一層,能處理更靈活的情境。

一、無窮迴圈 — while True:

什麼是無窮迴圈?

所謂「無窮迴圈」,
就是你不預設它什麼時候停,而是用 條件判斷 + break 來結束。

while True 的由來很「實務」:

很多互動或等待情境,你事先不知道要執行多少次(使用者會輸入幾次、外部事件何時發生)
你想寫一段「一直等、一直處理」的程式,直到某個條件發生才停。

這時候最直覺的做法就是把條件設為永遠成立
然後用明確的 break 在適當時機跳出。

想像守門員說:只要有人進門我就看著,有人說「掰掰」我就走。
while True: 就是「我會一直待命」,直到有人發出離場信號 (break)。

語法長這樣:

while True:
    # 永遠成立,直到你用 break 強制跳出

白話文就是:

「只要我沒叫你停,你就一直做下去。」是不是很像媽媽在旁邊一直碎念:
「快去寫作業、快去寫作業……」哈哈哈!(應該很有畫面!)

執行流程(步驟)

  1. 進入 while True:(條件永遠成立),執行迴圈內容。
  2. 在迴圈內檢查某些條件(輸入、事件、錯誤、超時):
    • 若條件達成 → break → 跳出迴圈(迴圈結束)。
    • 否則繼續下一次迴圈(回到步驟 1)。
  3. 迴圈結束後繼續後面的程式碼。

注意:若你忘記任何 break 或者 break 的條件永遠不會成立,就會造成真正的無窮迴圈(CPU 被吃滿,程式卡住)。

範例:數字猜謎遊戲

import random

answer = random.randint(1, 10)

while True:
    guess = int(input("猜一個 1~10 的數字:"))
    if guess == answer:
        print("🎉 猜對了!")
        break  # 猜對就結束
    else:
        print("再試一次!")

這種情境下你根本不知道玩家會猜幾次,所以 用 for 迴圈就不合適
while True 就成為最好的選擇。

輸出:
https://ithelp.ithome.com.tw/upload/images/20250929/20164721iZq2qJBlJd.png

二、while + else — 神秘用法

很多人不知道,while 其實也可以搭配 else

while … elseelse 並不是「如果條件不成立就執行」,
而是當迴圈完整跑完(沒有被 break 中斷)時才執行

換句話說:

  • 迴圈被 break 中止 → else 不會執行
  • 迴圈自然結束(條件變成 False)→ else 會執行一次

這跟 for … else 的規則是相同的。

為什麼會設計這個語法?

這個語法常用於「搜尋/檢查」類問題:
你在迴圈中找某個東西,如果找到就 break(不需要 else);

如果找完整個序列都沒找到,
就在 else 做收尾(例如提示「沒找到」或做補救處理)。

語法:

while 條件:
    # 重複執行
else:
    # 當迴圈「正常結束」才會執行這裡

重點

  • 如果是被 break 強制跳出 → else 不會執行
  • 如果是條件變成 False → else 才會執行

執行流程

  1. 檢查 while 條件:如果 False → 跳過迴圈直接跑 else(假如有 else)。
  2. 若 True → 執行迴圈內容。
  3. 若在某次迭代執行 break → 跳出迴圈,不執行 else
  4. 若迴圈最後因條件變 False 結束 → 執行 else(一次)。

範例 :密碼登入驗證

password = "python2025"
attempts = 3

while attempts > 0:
    guess = input("請輸入密碼:")
    if guess == password:
        print("✅ 登入成功")
        break
    else:
        attempts -= 1
        print(f"❌ 密碼錯誤,還剩下 {attempts} 次機會")
else:
    print("🚫 已達輸入上限,帳號鎖定")

這裡的 else 就很直覺:

  • 輸入正確 → break 跳出,else 不會執行。
  • 三次都失敗 → while 條件不成立,else 才執行鎖定訊息。

是不是很有「保底機制」的感覺?

輸出:(假設密碼連續輸入錯誤三次)
https://ithelp.ithome.com.tw/upload/images/20250929/20164721BD9DbgRXKf.png

輸出:(假設密碼輸入正確)
https://ithelp.ithome.com.tw/upload/images/20250929/20164721eVbo0JaMZK.png

範例:找第一個滿足條件的數字(找不到才做 else)

nums = [3, 5, 7, 11, 13]
target = 10

i = 0
while i < len(nums):
    if nums[i] > target:
        print("找到第一個大於 target 的數字:", nums[i])
        break
    i += 1
else:
    print("清單中沒有比 target 還大的數字")

輸出:
https://ithelp.ithome.com.tw/upload/images/20250929/20164721IXH3ij3vrO.png

範例:質數判斷

n = int(input("輸入 n > 1:"))
i = 2
if n <= 1:
    print("請輸入大於 1 的整數")
else:
    while i * i <= n:
        if n % i == 0:
            print(n, "不是質數,因為可被", i, "整除")
            break
        i += 1
    else:
        # 沒有任何小於 sqrt(n) 的因數 → 質數
        print(n, "是質數")

輸出:(若輸入非質數)
https://ithelp.ithome.com.tw/upload/images/20250929/20164721wHq7ZdJirP.png

輸出:(若輸入質數)
https://ithelp.ithome.com.tw/upload/images/20250929/20164721Tj69tvrr4d.png
解釋

  • 內部做 while i*i <= n 作為搜尋迴圈。
  • 若找到一個因數 → break → 代表不是質數 → else 不執行。
  • 若迴圈跑完都沒 break → else 執行,確認質數。

範例:檢查 list 是否全為正數(while … else

numbers = [5, 3, 7, -2, 10]
i = 0

while i < len(numbers):
    if numbers[i] < 0:
        print(f"❌ 第 {i+1} 個元素為負數: {numbers[i]}")
        break#有遇到負數就break,不管後面還有幾個負數
    i += 1
else:
    print("✅ 全部都是正數!")

輸出:
https://ithelp.ithome.com.tw/upload/images/20250929/20164721fobhNoAN1F.png

重點說明

  • while … else 的 else 只有在 迴圈沒有被 break 中斷 時才會執行。
  • break → 遇到負數就停止檢查。
  • i+1 → 因為索引從 0 開始,所以印出第幾個元素要加 1。

三、常見誤解與陷阱(重點+簡短範例)

誤解 1:while True = 一定不會結束

事實while True 會一直跑,除非你在迴圈裡有條件會 break

陷阱:忘記 break 或 break 條件永遠不會成立 → 無窮迴圈。

偵錯技巧:在迴圈裡加計數器與 print 或 log,
或者在開發階段暫時加上最大迴圈次數保護。

count = 0
while True:
    count += 1
    if count > 1000:
        print("警告:迴圈超過 1000 次,跳出(開發保護)")
        break

誤解 2:while-else 的 else 是「條件不成立時執行」

事實:不只是條件不成立,而是沒有被 break 中斷時會執行。
若迴圈一開始條件就不成立,else 也會執行(因為迴圈是「正常」結束)。

# 迴圈一開始就不成立
while False:
    print("不會執行")
else:
    print("會執行 else,因為迴圈正常結束(根本沒跑)"

誤解 3:把 break 放在內層時,會跳出所有巢狀層

事實break 只跳出當前層迴圈,不會直接跳到最外面。
若需要一口氣退出多層,可以設計旗標(flag)或拋例外,但不要亂拋。

實戰演練:簡易選課系統

這個程式模擬一個 學生選課系統

  • 系統提供五門課程:「Python,C,C++,Java,HTML」
  • 學生最多可以選 三門課
  • 使用 while 迴圈不斷要求輸入,直到選滿三門課

程式中也使用了 enumerate()break/continue,以及 while … else

print("=== 程式語言選課系統 ===")
courses = ["Python", "C", "C++", "Java", "HTML"]
selected = []

while len(selected) < 3:  # 最多選 3 門課
    print("\n可選課程:")
    for i, c in enumerate(courses, 1):
        print(f"{i}. {c}")

    try:
        choice = int(input("請輸入選課編號:"))
    except ValueError:
        print("⚠️ 請輸入有效數字")
        continue

    if 1 <= choice <= len(courses):
        course = courses[choice-1]
        if course in selected:
            print(f"⚠️ {course} 已選過,請選其他課程")
            continue
        selected.append(course)
        print(f"✅ 成功選擇 {course}")
    else:
        print("⚠️ 無效選項,請重新輸入")
else:
    print("\n✅ 選課完成!你選了:", selected)

這邊我會分成幾個區塊做詳細解說~讀者們不用擔心!

print("=== 程式語言選課系統 ===")
courses = ["Python", "C", "C++", "Java", "HTML"]
selected = []
  • courses:課程清單,存放可選的課程
  • selected:空 list,用來記錄學生已選的課程

輸出:
https://ithelp.ithome.com.tw/upload/images/20250929/20164721YdJNCgqwZR.png

while len(selected) < 3:  # 最多選 3 門課
  • 條件:len(selected) < 3 → 只要已選課程少於 3,就繼續迴圈
  • 這裡用 動態條件 控制迴圈,不用事先知道迴圈跑幾次
  • 一旦 selected 長度達 3 → 條件不成立 → 迴圈結束 → 執行 else
    print("\n可選課程:")
    for i, c in enumerate(courses, 1):
        print(f"{i}. {c}")
  • 每次迴圈都列出可選課程
  • enumerate(courses, 1) → 給每門課一個編號,從 1 開始
  • 讓學生輸入數字就可以選課
    try:
        choice = int(input("請輸入選課編號:"))
    except ValueError:
        print("⚠️ 請輸入有效數字")
        continue
  • try … except 捕捉輸入錯誤,例如輸入文字或空白
  • 如果轉換失敗 → 印出警告 → continue → 直接跳過本次迴圈,重新顯示課程
    if 1 <= choice <= len(courses):
        course = courses[choice-1]
  • 判斷輸入是否在有效範圍內(1 ~ 5)
  • courses[choice-1] → 把編號轉成課程名稱(因為 list 索引從 0 開始)
        if course in selected:
            print(f"⚠️ {course} 已選過,請選其他課程")
            continue
  • 檢查課程是否已選過
  • 如果已經選過 → 警告 → continue → 跳過本次迴圈,重新要求輸入。
        selected.append(course)
        print(f"✅ 成功選擇 {course}")
  • 將課程加入 selected 清單
  • 提示使用者選課成功
    else:
        print("⚠️ 無效選項,請重新輸入")

  • 如果輸入的數字不在有效範圍內(1~5)
  • 提示錯誤 → 重新輸入
else:
    print("\n✅ 選課完成!你選了:", selected)
  • while … else 的 else 區塊
  • 當 while 條件不成立時執行 → 也就是選滿三門課
  • 印出學生最終選課清單

完整輸出:

https://ithelp.ithome.com.tw/upload/images/20250929/20164721NHS0v0X7if.png

今日結語

今天我們實作了 while 迴圈的進階玩法

從基本條件控制到:

  • 動態條件:像選課系統一樣,條件會隨著 list 長度改變
  • while True + break:無限迴圈中控制退出時機
  • while … else:當迴圈自然結束時才執行的特別邏輯
  • continue:跳過不符合規則的輸入,保持程式流暢

透過實戰範例,我們學會如何:

  • 檢查重複輸入
  • 限制選課上限
  • 處理輸入錯誤

這些技巧讓迴圈不再只是「重複工人」,
而是能 智慧地控制流程、靈活應對各種情況的好幫手。

🔥 貼心小提醒:

鐵人賽已經進入一半啦!時間真的過得好快~
相信一天天堅持到現在的讀者們,也有很大的收穫!!
我也和螢幕前的你們,一同努力奮鬥中~
每天都會思考還有什麼實用的語法可以分享給大家~
也希望大家可以快樂的學習、有成就感的學習~

15天後的你,會感謝現在的你自己!!
我們一起堅持下去~那麼我們就明天見囉!!


上一篇
【Day14】條件驅動的迴圈魔法 — while 登場!
下一篇
【Day16】集合型態第二彈:Tuple 元組 ─ 不可動如山!
系列文
Python 小白的逆襲:30 天從零到能教人的精華筆記,寫給迷惘的你與當年的我自己!16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言