跳到主要內容

Day 6 迴圈進階與綜合練習

Day 6 迴圈進階與綜合練習

引言

昨天的內容中,我們認識了 for 與 while 兩種迴圈,並學會了 range()、break、continue 等控制流程的工具。那個時候的範例多半是「單層迴圈」,也就是一次只做一件事。但真實世界的問題往往更複雜,例如要處理二維的表格、產生重複的排列組合,或是寫一個小遊戲讓使用者反覆猜測。

這篇文章會帶你更深入迴圈的世界,從巢狀迴圈開始,了解如何用迴圈處理多層結構的資料。我們也會用兩個常見的小專案做綜合練習:九九乘法表與猜數字遊戲。這兩個範例會把條件判斷、迴圈、輸入輸出整合在一起,幫助你體會如何把基礎語法組合成完整的程式。

巢狀迴圈

巢狀迴圈指的是迴圈裡面還有迴圈。每次外層迴圈跑一次,內層迴圈就會完整地跑完所有輪次。這種結構非常適合用來處理二維資料,例如表格、矩陣或座標。

# 用迴圈印出 3x3 的座標
for row in range(3):
    for col in range(3):
        print(f"({row}, {col})", end=" ")
    print()  # 換行

輸出結果會依序印出 (0, 0)、(0, 1)、(0, 2),接著換行,再印 (1, 0) 到 (1, 2),以此類推。當外層是 3 輪、內層也是 3 輪時,總共會跑 3 × 3 = 9 次。巢狀迴圈雖然直覺,但要注意效能:層數越多,總執行次數成長得很快(外層 N 圈、內層 M 圈時,總共會跑 N × M 次)。當資料量大的時候,巢狀迴圈常常會成為效能瓶頸;這時候可以考慮改用向量化運算(例如 NumPy)或攤平資料結構,這個概念會在後續資料科學章節再次提到。

迴圈搭配 else 子句

昨天的內容已經簡單提過,Python 的迴圈可以搭配 else 子句。else 只會在迴圈「正常跑完」時執行,若用 break 中途跳出則不會執行。這個特性在做搜尋時特別好用,可以清楚區分「有找到」與「沒找到」兩種結果。

# 確認密碼是否符合複雜度要求
password = "abc123"
has_digit = False

for ch in password:
    if ch.isdigit():
        has_digit = True
        break
else:
    # 沒找到任何數字才會執行
    print("密碼必須包含數字")

if has_digit:
    print("密碼符合部分要求")

這段程式先用迴圈檢查密碼字串中有沒有數字;如果有,就用 break 提早結束,else 不會執行;如果都沒有,就會執行 else 區塊提示使用者。這個寫法比手動額外設一個布林旗標更簡潔,是 Python 推薦的慣用模式。

綜合練習一:九九乘法表

九九乘法表是巢狀迴圈的經典練習。我們用兩層 for 迴圈搭配 range(1, 10),就能印出完整的九九乘法表。

for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i} x {j} = {i * j}", end="\t")
    print()  # 每印完一列就換行

執行後會印出從 1×1=1 到 9×9=81 的完整乘法表。end="\t" 是用來讓印出的結果以 Tab 分隔,讓表格對齊;外層迴圈跑完一輪後,再用 print() 換行進入下一列。這個練習除了練習巢狀迴圈,也順便熟悉了 f-string 的格式化寫法。

如果你想讓格式更緊湊,也可以用下面的版本,只保留結果不顯示算式:

for i in range(1, 10):
    for j in range(1, 10):
        print(f"{i * j:2d}", end=" ")
    print()

其中 :2d 表示「以寬度為 2 的整數格式輸出」,可以讓個位數與兩位數對齊。

綜合練習二:猜數字遊戲

第二個練習是經典的猜數字遊戲:程式先隨機選一個 1 到 100 的數字,使用者反覆猜測,程式提示「太大」或「太小」,直到猜中為止。這個練習會用到 while 迴圈、if...elif...else 條件判斷,以及 random 模組。

import random

answer = random.randint(1, 100)
attempts = 0

while True:
    guess = int(input("請猜一個 1-100 的數字:"))
    attempts += 1

    if guess > answer:
        print("太大了,再小一點")
    elif guess < answer:
        print("太小了,再大一點")
    else:
        print(f"恭喜答對!你總共猜了 {attempts} 次")
        break

這個小遊戲展示了許多基礎語法的組合應用:import 用來載入模組,while True 加上 break 構成主迴圈,if...elif...else 判斷猜測的方向,f-string 顯示最終結果。執行幾次後你會發現,加上「太大/太小」的提示,使用者平均只需要 7 次左右就能猜中。

如果要進一步強化這個遊戲,還可以加上「超過 10 次就出局」、「允許重新開始」等功能。這些延伸功能會用到你已經學過的條件判斷與迴圈,是很棒的自我練習。

舉例來說,把「最多只能猜 10 次」加進去,只需要在外層加一個變數計數,並在迴圈內判斷是否超過上限即可:

import random

answer = random.randint(1, 100)
max_attempts = 10

for attempt in range(1, max_attempts + 1):
    guess = int(input(f"第 {attempt} 次猜測(剩餘 {max_attempts - attempt + 1} 次):"))
    if guess > answer:
        print("太大了")
    elif guess < answer:
        print("太小了")
    else:
        print(f"第 {attempt} 次就答對了!")
        break
else:
    # 用完次數仍未猜中
    print(f"挑戰失敗,正確答案是 {answer}")

這個版本結合了 for 迴圈、else 子句與字串格式化,把「有限的嘗試次數」與「未挑戰成功的提示」自然地寫在一起,是綜合運用本章所學的好範例。

迴圈的除錯技巧

當迴圈出錯時,有幾個常見的原因與對應的除錯方式可以幫你快速定位問題。

檢查迭代範圍:巢狀迴圈出問題時,最常見的原因是「外層與內層的範圍寫錯」。例如九九乘法表本應是 range(1, 10),但不小心寫成 range(10),就會印出 0×0=0 到 8×8=64 的錯誤版本。

確認 break 與 continue 的位置:break 與 continue 只會影響「最近的」迴圈。因此巢狀迴圈內若想中斷外層,需要額外設計旗標或把邏輯抽出來。

用 print() 追蹤過程:在迴圈內加上 print() 把關鍵變數印出來,是最直覺的除錯方法。例如猜數字遊戲如果一直提示「太小」,可以把 answer 印出來確認是否不小心把它設成比實際值大。

留意輸入格式:input() 永遠回傳字串,若需要做數值比較,必須用 int() 或 float() 轉換。忘記轉換會直接報 TypeError,這在猜數字、年齡判斷、成績等第等範例中非常常見。

實用範例:列印等差級數

把巢狀迴圈與累加結合,我們來列印一個「等差級數表」:第一層迴圈決定起始值,第二層迴圈負責累加固定的差值,最後把每一列的結果印出來。這樣的小練習能幫助你熟悉「外層決定結構、內層負責內容」的巢狀思維。

for start in range(1, 6):
    row = []
    for step in range(5):
        row.append(start + step * 2)
    print(row)
# [1, 3, 5, 7, 9]
# [2, 4, 6, 8, 10]
# [3, 5, 7, 9, 11]
# [4, 6, 8, 10, 12]
# [5, 7, 9, 11, 13]

這個範例展示了巢狀迴圈一個很典型的應用:「外層決定某一類的起點,內層負責生成同類的細節」。很多表格、矩陣、座標相關的問題都可以用這個思維拆解。

小結:迴圈的思維模型

迴圈的本質其實很簡單:把重複的動作交給電腦執行。當面對一個需要重複的事情時,先問自己三個問題:

  1. 要重複什麼?寫成縮排內的程式碼。
  2. 重複幾次?或什麼時候該停?決定用 for 還是 while。
  3. 每次重複之間狀態怎麼變?這就是計數器或迭代變數的設計。

把這三個問題釐清,迴圈的程式碼自然會浮現。當你熟悉這個思維後,就能從容面對九九乘法表、猜數字遊戲、甚至更複雜的演算法問題。

結語

今天我們從巢狀迴圈開始,認識了如何用兩層(甚至更多層)迴圈處理二維或重複的結構。我們也複習了迴圈搭配 else 子句的慣用模式,並用九九乘法表和猜數字遊戲做綜合練習,把條件判斷、迴圈、輸入輸出、模組載入等基礎語法組合成完整的程式。這樣的練習能幫助你把零散的語法串成真正的應用。

明天,我們會進入函式的世界。當程式碼越來越多,把常用的程式片段打包成函式就變得很關鍵。函式能讓程式碼更簡潔、更容易維護,也是後續學習物件導向與深度學習模型的基礎。

留言

這個網誌中的熱門文章

Day 2 變數與資料型別

Day 2 變數與資料型別 引言 寫程式的過程中,變數與資料型別是處理資料的基礎。變數是存放資料的容器,資料型別則決定這筆資料有哪些特性、可以進行哪些操作。學會定義變數、認識各種資料型別,是學好 Python 的關鍵一步。 這篇文章會帶你了解 Python 中變數的觀念、如何定義變數,以及常見的資料型別,包括整數、浮點數、字串、布林值,還有串列、元組、字典與集合等容器型別。我們也會介紹變數的命名規則與撰寫風格建議,以及如何用 type() 檢查資料型別。 什麼是變數?如何在 Python 中定義變數 變數是在程式執行時用來存放資料的名稱。透過定義變數,我們可以給一筆資料一個名字,並在程式的其他地方用這個名字取用該筆資料。在 Python 中,變數不需要事先宣告型別,因為 Python 是動態型別語言,變數的型別由指定給它的值決定。 定義變數的基本語法 在 Python 中定義變數非常簡單,只要用賦值符號 = 把值指定給變數即可。例如: x = 5 # 定義變數 x,並把整數 5 賦值給它 name = "Alice" # 定義變數 name,並把字串 "Alice" 賦值給它 在這裡,x 是一個變數,被賦予整數 5;name 是另一個變數,被賦予字串 "Alice"。 變數的更新與覆寫 變數的值可以修改,也就是說,我們可以在程式的不同地方給同一個變數新的值。例如: x = 10 # x 最初被賦予 10 x = 15 # x 的值現在被更新為 15 這樣就能依照需求,在程式執行過程中靈活調整變數的值。 Python 的動態型別系統 Python 和某些靜態型別語言不同,定義變數時不需要宣告型別。賦值時,Python 會根據值自動判斷變數的型別。例如: x = 5 # x 是整數 x = 3.14 # x 變成浮點數 x = "Hi" # x 變成字串 同一個變數在程式執行過程中可以存放不同型別的值,這是 Python 的彈性之一。 常見資料型別 在 Python 中,資料型別決定我們可以對變數進行哪些操作...

Day 1 Python 簡介與環境設定

Day 1 Python 簡介與環境設定 引言 在現在的科技環境裡,程式設計已經是一項重要技能。無論你是對資料科學有興趣、想成為開發者,或是想踏入人工智慧(AI)領域,學會寫程式都能明顯提升你的競爭力。在眾多程式語言中,Python 因為語法簡單、功能強大、應用範圍廣泛,成為許多人進入程式世界的第一選擇。這篇文章會帶你認識 Python 的背景與優勢,並一步步教你在不同系統上安裝與設定 Python 開發環境,最後寫出第一支 Python 程式。 為什麼選擇 Python? Python 是一種高階程式語言,由 Guido van Rossum 在 1991 年發布。Python 的設計哲學強調程式碼的可讀性,並用縮排來定義程式區塊,這點和許多使用大括號的語言不同。簡潔的語法讓它成為初學者的理想選擇;就算是經驗豐富的開發者,也能用它完成複雜的專案。 Python 的優勢如下: 簡單易學 :Python 的語法清楚、結構簡潔,初學者很快就能上手。和其他語言相比,學習曲線相對平緩,不需要先弄懂一堆複雜觀念,就能開始寫程式。 應用範圍廣泛 :從資料科學、網頁開發、人工智慧、機器學習、自動化測試到網路爬蟲,Python 都有大量開源函式庫與工具支援,而且在這些領域都扮演關鍵角色。 豐富的函式庫與框架 :Python 的函式庫生態系非常龐大。做資料分析有 NumPy、Pandas;開發網站有 Django、Flask;做深度學習有 TensorFlow、PyTorch。各種需求幾乎都能找到對應的套件,讓開發更有效率。 跨平台支援 :Python 支援 Windows、macOS、Linux 等作業系統,程式通常不需要太多修改就能跨平台執行,讓開發與部署更有彈性。 活躍的社群 :Python 擁有龐大的開發者社群。學習或開發上遇到問題,幾乎都能在社群與論壇(例如 Stack Overflow)找到答案,對初學者來說是很強的後盾,也能減少卡關時的挫折感。 Python 的應用領域 Python 的流行與強大功能,讓許多領域都開始大量使用它。以下是幾個常見的應用方向: 資料科學 :隨著大數據與人工智慧興起,資料科學大量使用 Python。NumPy、Pandas 與 Matplotlib 等工具能處理和分析龐...

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門 隨著人工智慧(AI)與深度學習(Deep Learning)快速發展,越來越多人對這些技術產生興趣。不論你是想踏入 AI 領域的初學者,還是已經有程式基礎的開發者,學好 Python 與深度學習框架(例如 PyTorch),都能為你打開更多可能。 為什麼選擇 Python? Python 已經是資料科學與人工智慧領域的首選語言。它的語法簡潔、容易上手,而且擁有龐大的生態系與大量開源函式庫。無論是資料處理、資料視覺化,還是建立機器學習與深度學習模型,Python 都能勝任。對想進入 AI 或資料科學領域的人來說,它幾乎是必備工具。 PyTorch 是什麼? PyTorch 是由 Meta(原 Facebook)AI 研究團隊開發的開源深度學習框架,以易用、靈活和動態計算圖著稱,是許多 AI 研究人員與開發者的首選。相較於其他框架,PyTorch 的寫法更貼近原生 Python,對初學者相對友善。無論是簡單的實驗,還是複雜的深度學習模型,PyTorch 都能提供強大的支援。 這個系列能帶給你什麼? 這個系列會從 Python 的基礎開始,帶你一步一步學習,最後能自己用 PyTorch 建立深度學習模型。即使你完全沒有寫過程式,也能跟著文章的節奏累積技能,理解 AI 與深度學習的核心觀念。 本系列涵蓋的主題 Python 基礎:從變數、條件判斷到函式與模組。 資料處理工具:用 NumPy 與 Pandas 有效率地操作資料。 資料視覺化:用 Matplotlib 與 Seaborn 把資料畫成圖表。 深度學習的數學基礎:線性代數、微積分與機率。 PyTorch 入門:理解張量、模型建構與 GPU 加速。 基礎深度學習模型:CNN 與 RNN 的實作應用。 深度學習專案實戰:從資料前處理到模型部署的端到端流程。 誰適合這個系列? 程式初學者 :如果你對 AI 充滿好奇,卻還沒寫過程式,系列的第一部分會帶你快速上手 Python,並幫助你理解深度學習的基本觀念。 資料科學愛好者 :如果你已經熟悉一些資料處理方法,進階部分會教你如何用 PyTorch 建構深度學習模型。 開發者與研究人員 :想更深入了...