2026年8月30日 星期日

巡查七座養殖場——break、continue與迴圈else

Python一下|第6篇

巡查七座養殖場——break、continue與迴圈else

《從風土資料到智慧生活的程式設計》——該逐筆處理、跳過本筆,還是立即停止?

本篇學習目標
  • 使用for走訪List與Dict資料。
  • 使用range()產生巡查編號。
  • 理解while適合「次數未知、直到條件改變」的工作。
  • 使用continue跳過本次、break停止整個迴圈。
  • 理解迴圈else是在「沒有遇到break」時執行。
  • 完成七座養殖場分層巡查與摘要程式。

一、迴圈是重複處理資料的工具

巡查七座養殖場時,不需要把相同程式複製七次。只要把養殖場資料放進容器,再使用迴圈逐筆處理,就能讓程式更短、更容易維護。

for

逐筆走訪已知資料

while

條件成立就持續執行

continue

跳過本次,繼續下一筆

break

立刻結束目前迴圈

二、for:逐座巡查養殖場

farms = [
    "一號養殖場", "二號養殖場", "三號養殖場",
    "四號養殖場", "五號養殖場", "六號養殖場",
    "七號養殖場"
]

for farm in farms:
    print(f"正在巡查:{farm}")

print("巡查程式結束。")

farm依序取得List中的每一個名稱。迴圈內縮排程式會重複執行,離開縮排後只執行一次。

使用enumerate()取得編號

farms = ["一號養殖場", "二號養殖場", "三號養殖場"]

for number, farm in enumerate(farms, start=1):
    print(f"第{number}站:{farm}")
為什麼不用farms.index(farm)若名稱重複,index()只會找到第一次出現的位置;enumerate()能安全取得當次編號。

三、range():產生重複次數

寫法產生內容說明
range(7)0~6從0開始,不包含7
range(1, 8)1~7從1開始,不包含8
range(1, 8, 2)1、3、5、7每次增加2
range(7, 0, -1)7~1倒數,步進值為-1
for number in range(1, 8):
    print(f"準備讀取第{number}座養殖場資料")

四、for與資料容器

走訪Dict的鍵和值

pond = {"水溫": 28.5, "鹽度": 18.2, "溶氧": 5.8}

for field, value in pond.items():
    print(f"{field}:{value}")

走訪List of Dict

farms = [
    {"名稱": "一號場", "在線": True, "水溫": 28.5},
    {"名稱": "二號場", "在線": False, "水溫": None},
    {"名稱": "三號場", "在線": True, "水溫": 29.1}
]

for farm in farms:
    print(farm["名稱"], farm["在線"], farm["水溫"])

五、while:直到條件改變才停止

while適合不知道要重複幾次的工作,例如讓使用者反覆輸入指令,直到輸入「結束」。

command = ""

while command != "結束":
    command = input("輸入『巡查』或『結束』:").strip()

    if command == "巡查":
        print("開始執行教學巡查。")
    elif command != "結束":
        print("無法辨識此指令。")

print("系統已結束。")
避免無限迴圈:while迴圈內必須有機會改變條件。若程式無法停止,可在Thonny按停止按鈕,或在終端機按Ctrl+C中斷。

六、continue:資料缺漏就跳過本次

continue不會結束整個迴圈,只會略過本次後續程式,直接進入下一筆。

records = [28.5, None, 29.1, None, 27.8]

for temperature in records:
    if temperature is None:
        print("本筆水溫缺漏,跳過計算。")
        continue

    print(f"有效水溫:{temperature:.1f}°C")
適合continue:缺漏值、格式錯誤、維護中設備、測試資料或明確不納入本次計算的紀錄。跳過時應留下原因,不能讓資料無聲消失。

七、break:找到關鍵狀況就停止搜尋

break會立刻離開目前所在的迴圈,後面的資料不再處理。

statuses = ["正常", "正常", "離線", "正常"]

for number, status in enumerate(statuses, start=1):
    print(f"檢查第{number}座:{status}")

    if status == "離線":
        print("找到離線設備,停止本次搜尋。")
        break
不要濫用break:若任務要求完整巡查並產生全場摘要,就不應遇到第一個異常便停止。此時應記錄問題後繼續;只有「找到第一筆即可」或「繼續執行可能不安全」時才使用break。

八、迴圈else:沒有遇到break才執行

迴圈的else不是「條件不成立」;它表示迴圈正常走完,過程中沒有被break中止。

statuses = ["正常", "正常", "維護中", "正常"]

for status in statuses:
    if status == "離線":
        print("找到離線設備。")
        break
else:
    print("所有資料已搜尋完,未找到離線設備。")

搜尋指定養殖場

farms = ["一號場", "二號場", "三號場"]
target = input("要搜尋的養殖場:").strip()

for farm in farms:
    if farm == target:
        print(f"找到:{farm}")
        break
else:
    print("巡查清單中沒有這座養殖場。")

while也可以搭配else

attempt = 1

while attempt <= 3:
    code = input(f"第{attempt}次輸入巡查碼:")
    if code == "USR2026":
        print("巡查碼正確。")
        break
    attempt += 1
else:
    print("三次皆未輸入正確巡查碼。")

九、break和continue的差異

指令本次剩餘程式後續迭代常見情境
continue略過繼續跳過缺漏或不合格資料
break略過全部停止找到目標或遇到不能繼續的狀況
兩者皆不用照常執行繼續完整處理所有資料

十、巢狀迴圈:場域與感測器

farms = ["一號場", "二號場", "三號場"]
sensors = ["水溫", "鹽度", "溶氧"]

for farm in farms:
    print(f"\n{farm}")
    for sensor in sensors:
        print(f"  檢查{sensor}感測器")

外層迴圈每執行一次,內層迴圈會完整走一遍,因此總檢查次數是「場域數×感測器數」。

巢狀break只結束內層:內層迴圈執行break後,外層仍會進入下一座場域。若要停止多層迴圈,建議先設定旗標,或學會函式後使用return重新設計流程。

十一、完整示範:七座養殖場巡查摘要

farms = [
    {"名稱": "一號場", "狀態": "正常", "水溫": 28.5},
    {"名稱": "二號場", "狀態": "維護中", "水溫": None},
    {"名稱": "三號場", "狀態": "正常", "水溫": 29.1},
    {"名稱": "四號場", "狀態": "離線", "水溫": None},
    {"名稱": "五號場", "狀態": "正常", "水溫": 31.2},
    {"名稱": "六號場", "狀態": "正常", "水溫": 27.9},
    {"名稱": "七號場", "狀態": "正常", "水溫": 28.2}
]

valid_count = 0
skipped_count = 0
attention_farms = []

for farm in farms:
    name = farm["名稱"]
    status = farm["狀態"]
    temperature = farm["水溫"]

    print(f"\n巡查{name}:{status}")

    if status != "正常" or temperature is None:
        print("  資料暫不納入數值分析。")
        skipped_count += 1
        continue

    valid_count += 1

    if not 25 <= temperature <= 30:
        print("  教學判讀:水溫需進一步確認。")
        attention_farms.append(name)
    else:
        print("  教學判讀:水溫位於示範範圍。")

print("\n===== 巡查摘要 =====")
print(f"總場數:{len(farms)}")
print(f"有效數值:{valid_count}")
print(f"跳過筆數:{skipped_count}")
print(f"需確認場域:{attention_farms}")
為什麼這裡不用break?目標是產生七座場域的完整摘要,因此離線或維護中的資料只用continue跳過數值分析,仍繼續巡查其餘場域。

十二、常見錯誤

錯誤原因修正
修改List同時遍歷刪除元素會改變索引走訪副本或建立新List
while永不停止條件變數未更新確認每輪都有終止機會
continuebreak混淆跳過與停止先用文字說明預期流程
以為迴圈else是if的else對齊層次看錯確認else與for或while同層縮排
巢狀迴圈break後外層仍執行break只影響所在迴圈使用旗標或函式重新設計
跳過資料卻不留紀錄摘要無法追查資料品質累計跳過筆數與原因

十三、漸進式練習

基礎:巡查編號

使用range(1, 8)輸出七座養殖場的巡查編號,再改用List與enumerate()輸出場域名稱。

進階:搜尋離線設備

使用for-else尋找第一個離線設備;找到時用break停止,全部搜尋完都沒有找到時才輸出「未發現離線設備」。

USR挑戰:資料品質報告

為每筆資料增加「正常、維護中、離線、缺漏」狀態,使用continue略過不可分析資料,同時統計各種略過原因;最後輸出完整巡查筆數,確保總數能核對。

十四、學習檢核

  1. forwhile適用情境有何不同?
  2. range(1, 8)為何可以得到1~7?
  3. continuebreak分別影響哪些迭代?
  4. 迴圈的else在什麼情況下執行?
  5. 巢狀迴圈中的break會不會停止外層?
  6. 為什麼完整巡查摘要通常不應遇到第一個異常就break?

十五、AI協作提示詞

請擔任Python迴圈助教。
我要以多座USR場域資料練習for、while、range、enumerate、
break、continue與迴圈else。

請先問清楚我的任務是:
1. 完整處理所有資料;2. 找到第一筆就停止;
3. 跳過不可用資料;或4. 搜尋完仍未找到才顯示訊息。

再依任務選擇是否使用break、continue或迴圈else,
並說明為什麼。跳過資料時要留下原因及統計,
不要捏造真實養殖數值或USR成果。

十六、延伸閱讀

十七、本篇小結

迴圈讓我們處理多座場域與多筆資料;continue適合跳過本筆但繼續工作,break適合找到目標或無法安全繼續時立即停止,迴圈else則用來表達「完整搜尋後仍未中止」。

場域巡查不只是跑完迴圈;每一筆跳過與每一次停止,都應有清楚理由,也都應留下可追查的紀錄。
系列:《Python一下:從風土資料到智慧生活的程式設計》
上一篇:《智慧養殖設備異常判斷——if、elif、巢狀判斷與in》
下一篇:《把智慧養殖計算交給lambda、map與filter》
教學定位:國立虎尾科技大學USR × 七座養殖場 × Python迴圈 × 資料品質

沒有留言:

張貼留言