Python 入門指南 5.0
單元 7 - 迴圈
程式 (program) 中的迴圈 (loop) 就是在特定程式區塊 (block) 中,重複執行相同的工作
pass
for i in condition:
pass
Python 中有兩種迴圈,分別是 while 迴圈 (while loop) 與 for 迴圈 (for loop) 。我們先來看看 while 迴圈的寫法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 設定控制變數
i = 10
# while 迴圈
while i > 0:
# 迴圈工作區
print(i)
# 調整控制變數值
i -= 1
# while 迴圈結束後執行
print("while 陳述後執行的部分")
# 檔名: while_demo.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月
|
這個迴圈所進行的工作很簡單,先在命令列上印出 10 ,然後一路遞減到 0 為止。迴圈有三個地方要注意
- 設定控制變數
- 條件
- 調整控制變數值
while 迴圈的控制變數 (control variable) 必須在 while 之前就先設定好,此例中將控制變數 i 設定為 10 。然後進入 while 的地方,條件 (condition) 就在 while 之後到冒號之前的地方,此例中為當控制變數 i 大於 0 時,迴圈便會重複執行。迴圈工作區,也就是 while 底下用縮排 (indentation) 的程式區塊,這裡,我們只有簡單的印出控制變數 i 的值,迴圈工作區的最後需要有調整控制變數值的地方。
來執行看看結果吧!執行結果如下
$ python while_demo.py |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
while 陳述後執行的部分 |
$ |
當我們明確知道重複次數的時候,我們得利用控制變數來記錄 while 迴圈所進行次數,這樣 while 迴圈才會有結束的一天,不然若是三個與控制變數相關的部份,漏了任一部份時,就有可能導致無窮迴圈 (infinite loop) 的發生,例如
i = 10 # 設定控制變數
while i > 0:
# 迴圈工作區
print(i)
# 沒有調整控制變數值
|
這樣一來,控制變數 i 永遠大於 0 ,所以迴圈會一直重複執行,此例中會不斷的在命令列印出 10 ,直到強制結束程式的執行為止。
另外一個 for 迴圈用於取得具有多個元素 (element) 的物件 (object) ,例如內建函數 (function) range() 回傳一個依序的 range 物件
for i in range(10, 0, -1):
# 迴圈工作區
print(i)
|
for 與 in 連用, in 後面接多個元素的物件。這個 for 迴圈的功能與上面的 while 迴圈完全相同,寫成完整的範例程式,如下
1 2 3 4 5 6 7 8 9 10 11 12 | # for 迴圈
for i in range(10, 0, -1):
# 迴圈工作區
print(i)
# for 迴圈結束後執行
print("for 陳述後執行的部分")
# 檔名: for_demo.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月
|
此例的 range() 用了三個參數 (parameter) ,第一個參數為起始值,第二個參數為結束值,第三個參數為遞增值。執行結果如下
$ python for_demo.py |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
for 陳述後執行的部分 |
$ |
雖然 while 迴圈與 for 迴圈可以互相替代,但還是依特性去使用比較適合囉!
迴圈中可以有另一個迴圈,這樣的迴圈稱之為巢狀迴圈,例如以下利用巢狀 for 迴圈印出九九乘法表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 巢狀 for 迴圈
for i in range(1, 10):
# 內層迴圈
for j in range(1, 10):
print("%(n)3d" % {"n" : i * j}, end = ", ")
print()
# 巢狀 for 迴圈結束後執行
print("巢狀 for 陳述後執行的部分")
# 檔名: nestedloop_demo.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月
|
執行結果如下
$ python nestedloop_demo.py |
1, 2, 3, 4, 5, 6, 7, 8, 9, |
2, 4, 6, 8, 10, 12, 14, 16, 18, |
3, 6, 9, 12, 15, 18, 21, 24, 27, |
4, 8, 12, 16, 20, 24, 28, 32, 36, |
5, 10, 15, 20, 25, 30, 35, 40, 45, |
6, 12, 18, 24, 30, 36, 42, 48, 54, |
7, 14, 21, 28, 35, 42, 49, 56, 63, |
8, 16, 24, 32, 40, 48, 56, 64, 72, |
9, 18, 27, 36, 45, 54, 63, 72, 81, |
巢狀 for 陳述後執行的部分 |
$ |
注意到第 5 行,在型態字元 d 之前的數字 3 表示佔據的字元數,這是說 3d 就表示變數 n 佔據三個字元的整數,如果 n 不到 3 位數就會填上空格
5 | print("%(n)3d" % {"n" : i * j}, end = ", ")
|
然後第 2 行及第 4 行,這裡 range() 用了兩個參數,第一個參數表示起始值,第二個參數表示結束值減 1 ,也就是到 9 為止的意思
2 4 | for i in range(1, 10):
for j in range(1, 10):
|
關鍵字 continue 可以讓迴圈直接進行下一輪,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 巢狀 for 迴圈
for i in range(1, 10):
# 依條件執行 continue
if i == 5 or i == 8:
continue
# 內層迴圈
for j in range(1, 10):
print("%(n)3d" % {"n" : i * j}, end = ", ")
print()
# 巢狀 for 迴圈結束後執行
print("巢狀 for 陳述後執行的部分")
# 檔名: continue_demo.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月
|
執行結果如下
$ python continue_demo.py |
1, 2, 3, 4, 5, 6, 7, 8, 9, |
2, 4, 6, 8, 10, 12, 14, 16, 18, |
3, 6, 9, 12, 15, 18, 21, 24, 27, |
4, 8, 12, 16, 20, 24, 28, 32, 36, |
6, 12, 18, 24, 30, 36, 42, 48, 54, |
7, 14, 21, 28, 35, 42, 49, 56, 63, |
9, 18, 27, 36, 45, 54, 63, 72, 81, |
巢狀 for 陳述後執行的部分 |
$ |
當執行到 i 為 5 及 8 時便執行 continue 陳述,因此 5 和 8 兩行並不會被印出來
4 5 | if i == 5 or i == 8:
continue
|
關鍵字 break 則可以中斷或跳出迴圈,例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # 巢狀 for 迴圈
for i in range(1, 10):
# 依條件執行 break
if i == 8:
break
# 內層迴圈
for j in range(1, 10):
# 依條件執行 break
if j == 7:
break
print("%(n)3d" % {"n" : i * j}, end = ", ")
print()
# 巢狀 for 迴圈結束後執行
print("巢狀 for 陳述後執行的部分")
# 檔名: break_demo.py
# 說明:《Python入門指南》的範例程式
# 網站: http://kaiching.org
# 作者: 張凱慶
# 時間: 2023 年 5 月
|
執行結果如下
$ python break_demo.py |
1, 2, 3, 4, 5, 6, |
2, 4, 6, 8, 10, 12, |
3, 6, 9, 12, 15, 18, |
4, 8, 12, 16, 20, 24, |
5, 10, 15, 20, 25, 30, |
6, 12, 18, 24, 30, 36, |
7, 14, 21, 28, 35, 42, |
巢狀 for 陳述後執行的部分 |
$ |
由於 i 為 8 及 j 為 7 的時候使用 break 陳述,因此橫向印到 6 為止,縱向印到 7 為止
4 5 10 11 | if i == 8:
break
if j == 7:
break
|
複合陳述除了選擇及迴圈外還有例外處理 (exception handling) ,所謂例外 (exception) 是指可預期的錯誤 (error) ,接下來我們繼續看到 Python 怎麼做錯誤控制。
程式區塊 | block |
條件 | condition |
控制變數 | control variable |
元素 | element |
錯誤 | error |
例外 | exception |
例外處理 | exception handling |
for 迴圈 | for loop |
函數 | function |
縮排 | indentation |
無窮迴圈 | infinite loop |
迴圈 | loop |
物件 | object |
參數 | parameter |
程式 | program |
while 迴圈 | while loop |
重點整理 |
---|
1. 迴圈用於重複性質的工作, while 迴圈利用控制變數決定何時結束迴圈, for 迴圈則用於具有多個元素的複合資料型態。 |
2. 無窮迴圈是指沒有結束條件,一直執行的迴圈。 |
3. 巢狀迴圈是指迴圈中其他迴圈的迴圈。 |
4. 利用 break 陳述可提前跳出迴圈。 |
5. 利用 continue 陳述可使迴圈直接進行下一輪。 |
問題與討論 |
---|
1. 很多情況都需要 while True 迴圈,這不是無窮迴圈嗎?那為什麼還要 while True 迴圈呢? |
2. while 迴圈與 for 迴圈要如何互相替代? |
3. 遞迴是一種演算法,遞迴跟迴圈有什麼不同呢? |
練習 |
---|
1. 寫一個程式 exercise0701.py ,利用迴圈計算 1 到 1000 的總和。 參考程式碼 |
2. 承上題,另寫一個程式 exercise0702.py ,改成接受使用者輸入,計算 1 到使用者輸入整數的總和。 參考程式碼 |
3. 迴圈中若有其他迴圈稱之為巢狀迴圈,利用巢狀迴圈及 '*' 寫一個程式 exercise0703.py,印出一個高 5 、底 5 的等腰直角三角形。 參考程式碼 |
4. 承上題,另寫一個程式 exercise0704.py ,將三角形倒過來印。 參考程式碼 |
5. 承上題,另寫一個程式 exercise0705.py ,改成接收使用者輸入邊長。 參考程式碼 |
6. 寫一個程式 exercise0706.py ,接收使用者輸入英文句子,計算母音字元數量,然後印出英文句子的總字元數與母音字元數。 參考程式碼 |
7. 寫一個程式 exercise0707.py ,在 while True 迴圈中接受使用者的輸入,當使用者輸入 'e' 的時候利用 break 跳出迴圈。 參考程式碼 |
8. 寫一個程式 exercise0708.py ,計算 10 的階乘,也就是從正整數 1 乘以正整數 2 ,一路乘到正整數 10 。 參考程式碼 |
9. 承上題,另寫一個程式 exercise0709.py ,改成接受使用者輸入,計算使用者輸入的階乘數。 參考程式碼 |
10. 費氏數列為 1 、 1 、 2 、 3 、 5 、 8 、 13 .... ,也就是後面的數字為前兩個數字的總和,寫一個程式 exercise0710.py ,計算出第 20 個數字。 參考程式碼 |
11. 承上題,另寫一個程式 exercise0711.py ,改成接受使用者輸入,計算使用者輸入的第幾個費氏數。 參考程式碼 |