# 迴圈 Loops 在處理資料的時候,常常會需要重複執行某些相同的步驟,此時我們需要**迴圈(loop)**,讓我們在一段程式中利用了短短幾行程式碼,就能連續執行多次重複動作,迴圈的作用是讓某段敘述在條件符合的情況下一直重覆執行,是程式設計中很重要的一種控制結構。 以下將介紹兩種迴圈:`while` 與 `for` ## 一、用 for 與 in 迭代 Python 經常使用迭代器(iterator)來遍歷一個資料結構 在Python中,可以用這種方式來遍歷: `for` 與 `in`是 Python 的關鍵字 `for` 與 `in` 之間放一個自訂變數,`in` 後面放一個可以迭代的資料(例如:一個字串、一連串的數字、一個list等等)。 ``` for variable in iterable object: statements ``` ### 1. 可迭代物件 (iterable) #### 可迭代物件 可迭代 (iterable) 簡單來說就是能用來產生迭代器的物件,回傳**其包含的所有元素**。 而上一節所提到的容器大部分是可迭代物件! ### 2. 遍歷容器 先前介紹的容器便是可迭代的資料結構,因此就可以利用`for...in`來遍歷。 > 範例 : 遍歷 list ```python=1 sequences = [0, 1, 2, 3, 4, 5] //宣告一個叫 sequences 的 list for i in sequences : // i是一個自訂變數 print( i, end = " " ) ``` >輸出 ``` 0 1 2 3 4 5 ``` > 範例:遍歷字串 ```python=1 word = "Hello" for letter in word: //一次產生一個字元來遍歷整個字串 print( letter ) ``` > 輸出 ``` H e l l o ``` `for...in` 不只可以用於遍歷資料,也可以是一串數字,如一開始提到的,我們要重複執行某項敘述時要怎麼辦呢? 這時就需要range()來協助。 ### 3. range() `range()` 函式用於連續回傳指定範圍內的一串數字 > 用法: ```python=1 range( start, stop, step ) ``` 使用 `range()` 時,要注意其中的三樣東西:初始值、終止值、每次遞增或遞減的變化。其中,`stop` 是唯一必要的值。若忽略 `start` 或 `step` , `start` 預設值會是0,而 `step` 則是1。 ```python=1 range(5) //從0到4 range(2,4) //從2到3 range(10, 2, -2) //從10到小於2, 公差為-2 ``` `range()` 會回傳一個可迭代的物件,簡單來說,`range()` 會幫我們產生一串連續數字的序列,因此我們可以搭配`for...in`來遍歷: > 範例 ```python=1 //使用for...in range()產生數字0123 for i in range(4) //從0開始到3結束 print( i ) ``` > 輸出 ``` 0 1 2 3 ``` 若要產生由大到小的數列,則`step` < 0 > 範例 ```python=1 //使用for...in range()產生數字 210 for i in range( 2, -1, -1 ) //從2開始到0結束 print( i ) ``` >輸出 ``` 2 1 0 ``` 我們利用range()來試試看如何遍歷一個容器 > 範例 : 遍歷容器 ```python=1 sequences = [0, 1, 2, 3, 4, 5] for i in range( len( sequences ) ): print( sequences[ i ], end = " " ) ``` 對比前面提到的遍歷容器範例,這支程式相對複雜。 當遇到需要遍歷一個可迭代的容器,就可以不用使用range()。 > 輸出 ``` 0 1 2 3 ``` ## 二、用 while 來重複執行 ``` while condition : statement ``` 這是一個簡單的迴圈,當條件成立時,則作以下的敘述,重複至條件不成立便會跳出迴圈。 > 範例 ```python=1 count = 1 while count <= 5: print(count, end = " ") count++ ``` > 輸出 ``` 1 2 3 4 5 ``` `while` 迴圈會先將 count 與 5 做比較,若 count 小於等於 5 則會繼續執行。迴圈中,會先印出 count 再將它的值遞增。接著,Python會回到迴圈的最上層,再次將 count 與 5 做比較。這個動作不斷循環,直到 `count <= 5`這個陳述句為`False`時,才會跳出迴圈。 > 無窮迴圈: ``` while True : statements... ``` 因為 `True` 恆為真,所以迴圈會一直進行。 --- #### for loop 與 while loop 的差異 多數的 `for` loop 程式都能用 `while` loop 實現,那麼什麼時候該用 `for`,什麼時候該用 `while`呢? 通常`for` loop 比較適用在已知迴圈數的問題,而 `while` loop 則適用在「無法預知迴圈數」的問題上。 當程式需要不斷地重覆某些運算,一直到出現指定的特殊狀況時才停止,這種情形就比較適合用 `while` loop 來實現。 ## 三、巢狀迴圈 巢狀迴圈意指在迴圈裡面又包著迴圈。 以外層迴圈的角度來看,內層迴圈只是一段敘述而已,因此外層迴圈每做一次,內層迴圈就要會整個迴圈完整跑一次,執行完畢後才跳回到外層迴圈準備下一次的動作。 若外層回圈要重複 i 次,內層迴圈重複 j 次,當外層迴圈完整跑完後,內層迴圈已經跑過 i * j 次。 前面所提到的 `for` loop / `while` loop都是屬於單層的,這適用於只有一個控制變數的反覆計算的情況。 若要處理的問題具有重複執行某段敘述的特性,但這段敘述受到兩個 (或兩個以上) 的變數來分別控制變化,此時就可以使用巢狀迴圈。 九九乘法就是一個很明顯有兩個控制變數的例子。 > 範例:九九乘法表 ```python=1 for i in range(1, 10): // 外層迴圈控制乘法前面的變數 i for j in range(1, 10): // 內層迴圈控制乘法後面的變數 j print('{I}*{J}={ans}'.format(I = i, J = j, ans = i * j ), end = " ") print() ``` ## 四、用 break 來跳出迴圈 執行迴圈時,常會遇到在特定的情況下,必須強制跳出迴圈的狀況,這時,就可以使用 `break` 當程式執行到迴圈內的 `break` 時,會中斷迴圈的執行,並且跳出整個迴圈,開始向下執行迴圈外的敘述。 因此,對於巢狀迴圈,若最內圈執行到 break 敘述時,則只會使最內圈的迴圈結束,而不是跳脫到整個巢狀迴圈結構外。 ![](https://i.imgur.com/Hrsmlf4.jpg) tip: 當我們使用無窮迴圈搭配break使用,就可以讓使用者在特定條件下跳出無窮迴圈。這樣的設計很適合使用在操作與使用者對話的程式! ``` while True: (do something) if (request) break ``` > 範例 ```python=1 while True: name = input("Please enter your name or enter Quit to leave the program:") if name == "Quit": break print("Hello," + name ) ``` 這段程式會請使用者輸入名字,並與使用者打招呼,重複持續到使用者輸入 `Quit` 為止。因為不知道使用者何時才會輸入 `Quit` 來停止程式,因此先使用無窮迴圈 `while true`,讀取使用者的輸入內容,並判斷輸入內容是否為 `Quit` ,是則將程式 `break` 掉,否則持續進行。 > 輸出 ``` Please enter your name or enter Quit to leave the program :Ken Hello, Ken Please enter your name or enter Quit to leave the program :Sandy Hello, Sandy Please enter your name or enter Quit to leave the program :Quit ``` ## 五、用 continue 來跳過 有時候基於某些原因,你不想跳出迴圈,只想跳過這次的迭代,並進行下一次的迭代,這個時候就可以用 continue 進行迴圈。 ![](https://i.imgur.com/7CKmkty.jpg) > 範例 : 印出小於10並整除3的數字 ```python=1 number = 0 while number <= 10: number += 1 if number % 3 != 0: continue # 若不能整除3,就跳過不引出數字,直接進行下一個數字的判斷 print(number) ``` > 輸出 ``` 3 6 9 ``` # 練習題 ## 是非題 1. ( ) 我們不能用 `for...in` 來遍歷 list,因為它不是一個可迭代的物件。 2. ( ) 下述的程式碼沒有任何 Error ```python=1 for i in range(5) print(i) ``` 3. ( ) 下述的程式碼沒有任何 Error ```python=1 for i in range(10) : for j in range(10) : print( i * j ) ``` 4. ( ) 承上題,電腦會執行10次 `print()` 的動作。 5. ( ) 在下述的程式碼中,迴圈只會執行五次。 ```python=1 i = 0 while True : if i = 5 : continue else i > 10 : break print(i) ``` ## 程式題 請設計一個程式讓使用者可以輸入一個正整數,作為金字塔的層數,並印出相應層數的* 金字塔