# Python 迴圈
By 極速車神大佬
credit: 資芽 2023, 2024 迴圈簡報
---
輸出 1 ~ 9 可以怎麼打 ?
```python=
print('123456789')
```
這時候還可以用手打的:
----
又像是輸出 1 ~ 99
```python=
print('123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899')
```
還是可以,但看起來很不切實際 !
----
觀察到 **我們其實是重複做類似的事情**
也就是「做很多次」 「列印一個數字」。
這時候我們就要用到一個很重要的東西 - 迴圈 !
---
## while 迴圈
----
### while 語法
```python=
while 判斷式:
指令 1
指令 2
```
觀察:
1. 與 if 類似,不過差別在 **會持續不斷的看判斷式是否成立,決定是否繼續執行**
2. 需要縮排
----

----
如果剛才的列印 1 ~ 99 用 while 迴圈寫出來:
1. 設定 `start` 初始為 1,並確認判斷式為 True
2. 輸出 `start`,並把 `start` 加上 1
3. 再次確認判斷式,直到若 `start <= 99` 不成立就退出
```python=
start = 1
while start <= 99:
print(start, end='')
start += 1
```
----
### 常用技巧 - 執行 N 遍
```python=
print('Hello World')
print('Hello World')
print('Hello World')
print('Hello World')
print('Hello World')
```
變成
```python=
i = 0
while i < 5:
print('Hello World')
i = i + 1 # 要記得加 !
```
1. 設定 `i` 初始為 0,並確認判斷式為 True
2. 輸出 `i`,並把 `i` 加上 1
3. 再次確認 `i < 5` ,若不成立就退出
這裡的 $i$ 決定了迴圈會執行幾次 !
----
### 無窮迴圈
迴圈若使用不恰當有可能會造成無窮迴圈,會一直運行無法停止 !
如果真的不小心戳到,可以按 ctrl+c 結束
```python=
i = 0
while i < 5:
print('Hello World')
# 沒有 i = i + 1, i 一直都是 0
# 每次 print() 結束後,條件式都一直是 True
```
```python=
i = 0
while i < 5:
print('Hello World')
i = i + 1 # 放錯位置 ! 這樣代表要等結束迴圈才加 1
```
----
### 用 while 迴圈計算 1 ~ 10 的和
先設一個變數 `total` 為 0,再依次加上 1~10
```python=
i = 1
total = 0
while i <= 10:
total += i
i = i + 1
print(total)
```
----
### 搭配 if
輸出 1 ~ 100 中**非 5 的倍數** [SPORUT OJ 728](https://tioj.sprout.tw/contests/7/problems/728)
Hint: 利用 if 判斷 $i$ 是否為 5 的倍數
:::spoiler 程式碼
```python=
n = int(input())
i = 1
while i <= n:
if i % 5 != 0:
print(i)
i = i + 1
```
:::
---
## Break
我想跳出迴圈...
除了讓判斷式不成立以外有其他方法嗎 ?
----
### 用 break ! 跑到 break 就會直接退出迴圈
### 通常會搭配 if 使用
```python=
while 迴圈的判斷式:
# 指令 ...
if 直接退出迴圈的判斷式:
break
# 指令 ...
```
----

----
例子:持續輸入數字,並列印數字的平方
如果輸入 -1 就結束。
```python=
while True:
x = int(input())
if x == -1:
break
print(x * x)
```
----
## continue
我想在迴圈中間跳過後面的指令:
----
### 用 continue ! continue 會直接跳過,並回到判斷式
### 通常也會搭配 if 使用
```python=
while 迴圈的判斷式:
# 指令 ...
if 直接退出迴圈的判斷式:
continue
# 指令 ...
```
----

----
剛才用 while 迴圈輸出 1 ~ 100 中**非**五的倍數
```python=
# 沒用 continue 版本
# 邏輯像是:不是 5 的倍數才輸出
n = int(input())
i = 1
while i <= n:
if i % 5 != 0:
print(i)
i = i + 1
```
```python=
# 有用 continue 版本
# 邏輯像是:是 5 的倍數會跳過輸出
i = 1
n = int(input())
while i <= n:
if i % 5 == 0:
i = i + 1
continue
print(i)
i = i + 1
```
----
( 可以嘗試使用 break 或不使用的寫法 )
[SPROUT OJ 683](https://tioj.sprout.tw/contests/7/problems/683)
---
## 巢狀迴圈
----
### 顧名思義,就是迴圈裡面又再包了一個迴圈
```python=
while 條件式1:
while 條件式2:
...
...
```
----
### 例子:99 乘法表

----
先小試身手:
Q:如果要輸出 1 * 1 ~ 1 * 9 要怎麼做 ?
A:設定 $i = 1$, $j=1 ... 9$
```python=
i = 1
j = 1
while j < 10:
print(f'{i} * {j} = {i * j}', end = ' ')
j += 1
```
----
延伸到 99 乘法表:讓 $i$ 從 $1 ... 9$,並執行剛才的輸出 $i * 1$ ~ $i * 9$
```python=
i = 1
while i < 10:
# 以下會輸出 i * 1 = i, i * 2 = 2i, ... i * 9 = 9i
j = 1
while j < 10:
print(i, '*', j, '=', i * j, end = ' ')
j += 1
i += 1
print() # 換行
```
----
### 練習
[SPROUT OJ 680](https://tioj.sprout.tw/contests/7/problems/680)
---
## for 迴圈
另一種迴圈 ?
----
### for 語法
```python=
for 變數 in 一串東⻄(可迭代物件):
指令 1
指令 ...
```
----
可迭代物件 ( iterable objects ) 能夠讓變數走遍整個物件
常見的包括:list, tuple, set, dictionary, range...
----
來看一些例子:
----
```python=
for i in 4, 8, 7, 6, 3:
print(i)
```
意思是:
- 對於所有的 $i$, $i$ = 4, 8, 7, 6, 3
- 執行 `print(i)`
----
相等於:
```python=
i = 4
print(4)
i = 8
print(8)
i = 7
print(7)
i = 6
print(6)
i = 3
print(3)
```
----
```python=
# i = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
for i in range(10):
print(i)
# i = 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
for i in range(10, 20):
print(i)
# i = 10, 12, 14, 16, 18
for i in range(10, 20, 2):
print(i)
```
----
常見的三種 `range()` 的用法:
1. 首項為 `0`,上界為 `i`, 公差為 `1`
```python
range(i)
```
2. 首項為 `i`,上界為 `j`, 公差為 `1`
```python
range(i, j)
```
3. 首項為 `i`,上界為 `j`,公差為 `k`
```python
range(i, j, k)
```
----
將 [SPORUTOJ 728](https://tioj.sprout.tw/problems/728) 改成 for 版本 !
```python=
n = int(input())
for i in range(1, n + 1): # 注意是 n + 1 不是 n
if i % 5 != 0:
print(i)
```
----
continue, break 在 for 的概念完全一樣 !
----
用 for 寫的 99 乘法表
簡潔 !
```python=
for i in range(1, 10):
for j in range(1, 10):
print(i, '*', j, '=', i * j, end = ' ')
print()
```
---
### 整理
while 迴圈不知道會何時終止,交給判斷式決定。
for 迴圈透過走遍一串東西,能確定執行多少次。
----
注意 while 的終止條件,不要製造出無窮迴圈
---
上課作業:
[SPORUT OJ 728](https://tioj.sprout.tw/contests/7/problems/728)
回家作業:
[SPROUT OJ 683](https://tioj.sprout.tw/contests/7/problems/683)
[SPROUT OJ 680](https://tioj.sprout.tw/contests/7/problems/680)
[SPROUT OJ 729](https://tioj.sprout.tw/contests/7/problems/729)
{"title":"Python 迴圈","description":"有時候我們想一次做多點工作:","contributors":"[{\"id\":\"6a375517-4167-4b7c-a983-1e595a29262c\",\"add\":10045,\"del\":4720}]"}