# 4. 迴圈

## I. 迴圈的用途

* 重複地做一樣的事情
* 用某個條件判斷決定是否結束不斷重複的輪迴

> 想想看，日常生活中有那些不斷重複做的事情呢?&#x20;

![](https://i.imgur.com/19fgraj.png)

在Python程式語言當中，迴圈有兩種表示方法：`while` 和 `for`

## II. `while`迴圈

### A. `while`迴圈的基本架構

```python
count = 0   # step1. while迴圈前需要一個計圈變數用於計算迴圈執行了幾圈

while count < 10:  # step2. while後方須接上判斷條件，判斷正確即可進入迴圈

    print(count)   # step3. 須要重複做的事

    count += 1   # step4. 迴圈將結束前，將計圈變數做點變化(否則會成為無窮迴圈)
```

> &#x20;執行步驟：step1 → step2 → step3 → step4 → (step2 → step3 → step4)×n次

**注意!** **縮排**也別忘了唷!

**注意!** step1 (計圈變數) 通常有各式型態，接下來我們就會陸續見到

`while`迴圈撰寫時可能會遇到的錯誤情況

```python
# 沒有於迴圈前有個計圈變數的情況
while count < 10: # NameError: name 'i' is not defined
    print(count)
    count += 1
```

```python
# 計圈變數放置於迴圈內的情況
while count < 10: # NameError: name 'i' is not defined
    count = 0
    print(count)
    count += 1
```

```python
# 沒有在迴圈將結束前，將計圈變數做變化
count = 0
while count < 10: # 永遠滿足判斷條件(無法跳出迴圈)
    print(count)
```

```python
# 判斷條件永遠錯誤，無法進入迴圈
count = 11
while count < 10: # 永遠無法滿足判斷條件(無法進入迴圈)
    print(count)
    count += 1
```

【下方為正確撰寫方式】

```python
# 嘗試執行下方的程式碼並觀察結果
count = 0
while 0:
    print(count)
    count += 1
```

```python
# 嘗試執行下方的程式碼並觀察結果
count = 0
while 2 and count < 15 or False:
    print(count)
    count += 1
```

```python
# 嘗試執行下方的程式碼並觀察結果
count = 8
while count < 16:
    print(count)
    count += 2
```

【例題1】

> &#x20;小蚯很喜歡`~`符號\
> &#x20;請寫一個程式能夠讀入一個整數\
> &#x20;再印出該整數個`~`符號

```python
count = int(input("請輸入次數：")) # 先利用一個變數儲存所輸入的整數

i = 0  # 計圈用變數
while i < count:  # 圈數還沒達到目標時
    print('~', end='') 
    i += 1  # 改變計圈用變數的值
```

【例題2】

> &#x20;家裡最近領養了一頭神牛超會算數學，只要給他一個數字，他就能加總出從1到該數字的總和\
> &#x20;**輸入說明**\
> &#x20;讓使用者能夠輸入一個正整數\
> &#x20;**輸出說明**\
> &#x20;若輸入值為10，則輸出55

```python
n = int(input("請輸入次數："))

i = 1 # 計圈用變數
sum = 0 # 創造一個變數用來儲存每一輪迴圈計算出的值

while i <= n:  # 圈數還沒達到n時繼續
    sum += i  # 將每輪計算出的結果儲存在sum變數中
    i += 1  # 改變計圈用變數的值

print(sum)
```

### B. 多變的迴圈

有時候，我們不必使用計圈變數來控制迴圈次數，而是直接改變`while`的判斷條件來讓迴圈停止

&#x20;通常這種寫法用於不確定迴圈需要進行幾圈的情況下

【例題1】

> 小奇有一個很特殊的個性，就是非常討厭偶數，只要看到偶數，就會反覆把它除以二，直到這個數字變成奇數為止。若現在給一個正整數，請問這個數字經過小奇的處理之後，會變成多少呢？

```python
i = int(input('請輸入一個正整數：'))

while i % 2 == 0: # 如果 i 為偶數，就進入迴圈
    i /= 2 # 每一輪將i值除以2

print(i) # 印出最終已成為奇數的 i 值
```

【例題2】

> &#x20;嘗試輸入各種血型來觀看今年的運勢(輸入`00`可結束此程式)

```python
i = '' # 先將i初始為一個非00的值(為了能進入迴圈)

while i != '00': # 當輸入值為00時結束迴圈
    i = input('請輸入一個血型：')
    if i == 'A' or i == 'a':
        print('今年桃花運很旺')
    elif i == 'B' or i == 'b':
        print('今年金錢運很旺')
    elif i == 'AB' or i == 'ab':
        print('今年工作運很旺')
    elif i == 'O' or i == 'o':
        print('今年驚喜運很旺')

print('程式已結束') # 印出 程式已結束 字樣
```

偶爾，我們會期待迴圈能永遠執行下去，永不停止

【例題3】

> 請撰寫一個能讓使用者輸入成績進而判斷：及格、可補考、死當

```python
# 結合了迴圈，就能夠實現重複不斷輸入的效果
while 1:
    num = int(input("請輸入一個分數:"))
    if num >= 60:
        print("及格")
    elif 40 <= num <60:
        print("可補考")
    else:
        print("死當")
```

【例題4】

> 請撰寫一個能夠不斷印出小印地安人的程式

```python
# 結合了迴圈，就能夠實現重複不斷輸入的效果
i = 1  # 計圈變數一開始設為1
while True:
    print(i, 'little Indian')
    i += 1  # 每輪結束前將計圈變數做變化
```

### C. 讓迴圈中途停止或跳過迴圈中的某圈

#### `break`

從上方【例題2】中我們可以發現，需要讓迴圈在`i`值為 `'00'` 時結束，須於 `while` 外頭先宣告 `i` 變數，讓程式碼看起來似乎有那麼一點不完美，這時，若我們能使用`break`即能夠避免這樣的情形

> `break`：當電腦執行到`break`時會**立即**終止**該層**迴圈

【例題】

上方【例題2】的改寫

```python
# 嘗試執行下方的程式碼並觀察結果
while True: 
    i = input('請輸入一個血型：')
    if i == '00':
        break   # 當輸入值為00時結束迴圈
    elif i == 'A' or i == 'a':
        print('今年桃花運很旺')
    elif i == 'B' or i == 'b':
        print('今年金錢運很旺')
    elif i == 'AB' or i == 'ab':
        print('今年工作運很旺')
    elif i == 'O' or i == 'o':
        print('今年驚喜運很旺')

print('程式已結束') # 印出 程式已結束 字樣
```

#### `continue`

偶爾，我們會希望當某個條件成立時，不做某件事而直接進行下一輪迴圈，這時，我們就可以使用`continue`

> `continue`：當電腦執行到`continue`時會**立即**跳過該輪迴圈，直接進行下一輪

【例題】

請製作一個倒數器，讓使用者輸入一個正整數後，即從該正整數開始不斷 -1 直至數到 1 為止，但中間過程若數到 5 的倍數，請跳過

```python
i = int(input('請輸入一個正整數：'))

while i: 
    if i % 5 == 0:
        i -= 1 # 這裡也必須要 -1 否則會形成無窮迴圈(為什麼？)
        continue # 立刻進行下一輪迴圈
    else:
        print(i, end=' ')
        i -= 1
```

想想看，上方的 `i -= 1` 與 `continue` 可以互換位置嗎?

由於`continue`的特性，我們其實能省略`else`，因此可將上方程式碼改寫如下：

```python
i = int(input('請輸入一個正整數：'))

while i: 
    if i % 5 == 0:
        i -= 1
        continue
    print(i, end=' ')
    i -= 1
```

## III. `for`迴圈

`for`迴圈跟`while`迴圈用法相似，最主要區別是在`while`迴圈通常會用於不知道要執行多少圈的情況下，而`for`迴圈通常用在已經知道要執行多少次的情況\
&#x20;例如：<br>

> &#x20;1\. 印出100個`Hello`\
> &#x20;2\. 算出某個數字的某次方\
> &#x20;3\. 算出某個數字的階乘

**注意!** 若不希望計圈變數在每一圈的變化值都相同，使用`while`會優於用`for`

### A. `for`迴圈的基本架構

`for`迴圈中也必須有一個計圈變數用來計算目前執行了幾圈，只是計圈變數放在`for`迴圈結構中。 【每輪迴圈完畢後，計算圈數的變數會產生變動】

以下三種為`for`迴圈常見的架構

```python
# range內只放一個數的情況
for i in range(6): # i會從0-5(不包含6)，每輪i都會+1
    print(i)
```

```python
# range內放兩個數的情況
for c in range(2, 6): # c會從2-5(不包含6)，每輪c都會+1
    print(c)

for c in range(-6, 2):  # c會從-6~1(不包含2)，每輪c都會+1
    print(c)
```

```python
# range內放三個數的情況
for x in range(21, 6, -3): # x會從21-6(不包含6)，每輪x都會-3
    print(x)
```

### B. `for` 與 `while` 間的轉換

兩者功能相同，也都需要一個計圈變數來記錄總共跑了幾圈。(唯`while`較簡便使用於無窮迴圈的情況下)

【例題】

```python
for i in range(6):
    print(i)

# 可改寫為：

i = 0
while i < 6:
    print(i)
    i += 1
```

```python
for c in range(2, 6):
    print(c)

# 可改寫為：

c = 2
while c < 6:
    print(c)
    c += 1
```

```python
for x in range(21, 6, -3):
    print(x)

# 可改寫為：

x = 21
while x > 6:
    print(x)
    x -= 3
```

### C. `for` 迴圈的計圈變數

`for` 迴圈中的計圈變數`i`沒辦法於`range`範圍中做更動，舉個範例如下

```python
for i in range(2,5):
    i=1 # 將計圈變數改為1
    print(i, end=' ') # 印出計圈變數
# 執行結果為：1 1 1 
```

即使想將過程中的`i`改為1，但在`range`中實際上它仍是2 3 4 ，因為在執行`range`時，它就已經將`i`值存在一個陣列中，無法更動

### 補充：迴圈搭配 `else`

`python`的迴圈有個很特殊的用法，即是能夠搭配`else`使用，若迴圈沒有在中途結束執行，就會執行`else`，舉個範例如下

```python
for i in range(3):
    print(3, end='')
else:
    print("前面迴圈沒有中斷")

# 執行結果為：&&&前面迴圈沒有中斷
```

```python
for i in range(3):
    print(3, end='')
    if i==2:
        break
else:
    print("前面迴圈沒有中斷")

# 執行結果為：&&&
```

## IV. 巢狀迴圈

### A. 巢狀迴圈的意義

巢狀迴圈顧名思義就是迴圈中還有迴圈的概念囉\~\~

> 相信大家對積木程式都已經不陌生了，先回想看看這題應該如何解? ![](https://i.imgur.com/v9qk0Zp.png)

先利用迴圈走完一個小三角形 ![](https://i.imgur.com/cUnh6EU.png)

再利用一個迴圈走完12個相同的小三角形 ![](https://i.imgur.com/ytncKoy.png)\
&#x20;

### B. 巢狀迴圈的範例

【例題1】

> &#x20;據說變態的人都喜歡打`A`\
> &#x20;設計一個能讓使用者輸入**列**和**行**的程式\
> &#x20;例如：列為3，行為5時，輸出：\
> &#x20;AAAAA\
> &#x20;AAAAA\
> &#x20;AAAAA

{% hint style="info" %}
思路：

1\. 印出A

2\. 重複?次

3\. 換一行

4\. 1\~3重複?次
{% endhint %}

```python
row, col = map(int, input("請輸入列與行：").split())

# 跑row圈(印出row個橫列)
for i in range(0, row): 

    # 跑col圈(在第i圈印出col個A)
    for j in range(0, col): 
        print("A", end="")

    print()
```

#### 用`while`改寫

```python
row, col = map(int, input("請輸入列與行：").split())

# 跑row圈(印出row個橫列)
i = 0
while i < row: 

    # 跑col圈(在第i圈印出col個A)
    j = 0 # 思考看看，如果此行與上一行程式碼位置互換結果會如何?
    while j < col: 
        print('A', end='')
        j += 1 
    print()
    i += 1 # 想想看，這行程式碼位什麼要往前移動
```

【例題2】

> &#x20;輸入n，輸出n行星號，第一行有一個\
> &#x20;每往下一行，就多一個星號\
> &#x20;例如：n為4時，輸出如下\
> &#x20;\*\
> &#x20;\*\*\
> &#x20;\*\*\*\
> &#x20;\*\*\*\*

{% hint style="info" %}
思路：

1\. 印出" "

2\. 重複?次

3\. 印出"\*"

4\. 重複?次

5\. 換一行

6\. 1\~5重複?次
{% endhint %}

```python
n = int(input("請輸入一個正整數："))

# 跑n圈(印出n個橫列)
for i in range(0, n): 

    # 每一輪j值的上限隨i變化而變化(即：在第i圈印出ｉ個＊)
    for j in range(0, i+1): 
        print("*", end="")

    print()
```

思考看看，第二個`for`迴圈為何上限寫`i+1`而非`i`

你也可以這樣改寫

```python
n = int(input("請輸入一個正整數："))

# 跑n圈(印出n個橫列)
for i in range(1, n+1):

    # 每一輪j值的上限隨i變化而變化(即：在第i圈印出ｉ個＊)
    for j in range(0, i):
        print("*", end="")

    print()
```

用`while`改寫

```python
n = int(input("請輸入一個正整數："))

# 跑n圈(印出n個橫列)
i = 1
while i < n+1: 

    # 每一輪j值的上限隨i變化而變化(即：在第i圈印出ｉ個＊)
    j = 0
    while j < i: 
        print('*', end='')
        j += 1

    print() 
    i += 1
```

### C. 巢狀迴圈中的 `continue` 與 `break`

**`break`**&#x8207;**`continue`**&#x90FD;僅作用於本身所存在的該層迴圈而已

```python
for i in range(5):
    for j in range(5):
        if j == 3:
            continue
        elif j == 4:
            break
        print(j, end=' ')
    print()
```

上方程式碼執行後的結果如下：

```python
0 1 2 
0 1 2 
0 1 2 
0 1 2 
0 1 2
```

## III. 學習單

{% embed url="<https://docs.google.com/presentation/d/e/2PACX-1vStIb8amiWJSmiy2NIncHlyRTyU9GlQ23g7Q3ot1dT8FBLoXk9P37ufONLXgzA30EwFr7hx25hbwd6Y/embed?start=false&loop=false&delayms=3000>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://simplife.gitbook.io/python/xin-shou-cun/hui-quan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
