# 迴圈 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 敘述時,則只會使最內圈的迴圈結束,而不是跳脫到整個巢狀迴圈結構外。

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 進行迴圈。

> 範例 : 印出小於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)
```
## 程式題
請設計一個程式讓使用者可以輸入一個正整數,作為金字塔的層數,並印出相應層數的* 金字塔