python的迴圈與流程控制

星期二 16 Apr 2019   even  
教學

前言

你可能會納悶,有些任務,直接打開excel或是直接開某某軟體,按個幾下不就處理好了嗎? 為什麼還要特地寫一個程式呢?

確實,當你的任務是一次性的作業時,直接手動使用相關軟體處理,工作速度會比編寫程式還快。但是,如果這項任務是重複性的任務,例如:對多個相似的檔案做某某事情時,你只要寫好一次程式,放進迴圈裏面,就可以輕鬆重複幫你執行上千次上萬次。這也就是本章節要介紹的重點,迴圈的使用。

另外,在重複執行的過程中,你會需要使用如果(if)來進行流程控制(flow control),設定當某某情況發生時,做某某事情,否則就做某某事情。

例如以下的程式碼:

weekday = ['禮拜一', '禮拜二', '禮拜三', '禮拜四', '禮拜五', '禮拜六', '禮拜天']

for day in weekday:
    print(f'今天是{day}:')
    if day in ['禮拜六', '禮拜天']:
        print('  假日!出門玩好開心~~')
    else:
        print('  工作日!不能出門玩~~嗚嗚')

今天是禮拜一:
工作日!不能出門玩~~嗚嗚
今天是禮拜二:
工作日!不能出門玩~~嗚嗚
今天是禮拜三:
工作日!不能出門玩~~嗚嗚
今天是禮拜四:
工作日!不能出門玩~~嗚嗚
今天是禮拜五:
工作日!不能出門玩~~嗚嗚
今天是禮拜六:
假日!出門玩好開心~~
今天是禮拜天:
假日!出門玩好開心~~

是不是很方便呢? 語法也很直觀呢? 是不是都還沒都介紹就大概看得懂在這段程式碼在做什麼了吧?

OK~那我開始正式介紹迴圈與流程控制在python裡面要怎麼使用。

for 迴圈

斯斯有兩種,而迴圈也有兩種,for與while,首先我們先來介紹for迴圈。

for迴圈是針對可迭代物(如: 清單)所使用的,會依序將你設定的任意變數,替換成迭代物內的每個元素,從第一個元素執行到最後一個。

因此,你的可迭代物有多長,他就會執行幾次。

要執行迴圈的程式,需要加上縮排 (indentation,四個空白或tab),python是以縮排來表示這一大段程式碼是在這個迴圈裡面。

使用範例如下:

mylist = ['你好', '我好', '大家好']


# 將mylist內的每個元素以i來表示,可以改用任意名稱,最後面要加上:
for i in mylist: 
    print(i) # 一定要加縮排,不然會碰到indentation error

你好
我好
大家好

mylist = ['你好', '我好', '大家好']

for item in mylist:
    print('哈囉') 
    for char in item: # 在for裡面在放一個for,因為字串也是iterable,也是可以直接放進迴圈裡
        print(char) # 此時需再加上一個層級的縮排以區隔

哈囉


哈囉


哈囉


另外,使用range來當iterable也是很常見的用法,如下:

for i in range(3):
    print(i)

0
1
2

while 迴圈

與for迴圈不同,不需要有iterable,但需要附上條件判斷,當條件判斷的結果是True時則會一直執行,直到條件判斷的結果為False時才停止。

如下:

while 3 > 0:
   print('hi')

3永遠都會大於0,所以會一直執行print('hi'),這是一個無限迴圈,除非強制關掉,否則就一直執行下去。你可以按下Ctrl + C來強制關掉運行中的程式。

很明顯的,上面的例子並不是while迴圈最恰當的用法,一般的使用會讓條件判斷有可能會變成False,如下:

a = 5
while a > 0:
    print(a)
    a -= 1
print('The loop is ended!')

5
4
3
2
1
The loop is ended!

當a大於0時執行下面的程式,而下面的程式裡面每執行一次a的數值會減1,因此當a不再大於0時,這個迴圈就斷掉了。

if 流程控制

如果 條件一為真 則做這些事情,又如果 條件二為真 做那些事情,除此之外則做另外的事情。以上是所有程式語言都會有的基本if -> else if -> else的套路,而python也是以同樣的方式來呈現。else if 在python的語法為elif,可以隨你的需求添加任意數量的elif。

如下:

today = '禮拜三'

if today in ['禮拜六', '禮拜天']:
    print('  假日!出門玩好開心~~')
elif today == '禮拜三':
    print('  今天要爬山~')
elif today == '禮拜五':
    print('  今天要跳舞~')
else:
    print('  工作日!不能出門玩~~嗚嗚')

今天要爬山~

是不是很直觀呢?

另外,再次提醒要注意indentation,python不像其他語言,額外使用括號來區隔開程式碼的區塊(block),而是改以indentation來區隔block。

只要出現 : 代表下一行開始一定要加縮排。

控制迴圈

除了用if來控制迴圈的執行流程外,python還提供pass、continue、break這三個關鍵字來更有效的控制迴圈的流程。

pass: 跳過,什麼都不做

continue: 立刻跳到下一個迭代

break: 立刻中斷迴圈

這三者通常會和if一起使用,確保迴圈能夠避免各種錯誤,如下面的例子想要顯示-3到2之間的倒數:

for i in range(-3,3):
    print(1/i)

print('Success')

-0.3333333333333333
-0.5
-1.0
Traceback (most recent call last):

File "<ipython-input-5-80d45d46ff5f>", line 2, in <module>
print(1/i)

ZeroDivisionError: division by zero

因為除法中的除數不能為0,因此當迴圈執行到i等於0的時候,就會出現ZeroDivisionError,使得整個程式斷掉。接下來的所有程式碼也就不會被執行。

可以使用if和pass、continue、break的組合來避免,如使用pass:

for i in range(-3,3):
    if i == 0:
        pass
    else:
        print(1/i)

print('Success')

-0.3333333333333333
-0.5
-1.0
1.0
0.5
Success

當i等於0時,跳過,什麼事都不做,除此之外才去取倒數。

此時,你可能會想,既然pass表示什麼都不做,何不直接在if底下完全留白呢? 如下:

for i in range(-3,3):
    if i == 0:
        
    else:
        print(1/i)

File "<ipython-input-9-4a41712ca20b>", line 4
else:
^
IndentationError: expected an indented block

無法,在if或for、while底下,你一定要有些東西,否則會報錯,這也就是pass的主要用法。

接著是以continue來避免ZeroDivisionError的方式,如下:

for i in range(-3,3):
    if i == 0:
        continue        
    print(1/i)

print('Success')

-0.3333333333333333
-0.5
-1.0
1.0
0.5
Success

你可以注意到我沒有用else,因為當執行到i等於0的時候,程式碼看到了continue,立刻執行下一個迭代,因此1/0不會被執行到。

最後是break,直接中斷掉迴圈,但是迴圈之後的指令依然會被執行,如下:

for i in range(-3,3):
    if i == 0:
        break        
    print(1/i)

print('Success')

-0.3333333333333333
-0.5
-1.0
Success

當碰到i等於0的時候,迴圈直接斷掉,之後的i等於1、2也就不會被執行,直接執行迴圈下面的指令。

Bonus Tip 1: List Comprehension

python提供了一項簡短但依然相當值觀的方式將for迴圈改寫成一行的式子,這套方式就是list comprehension,使用方式如下:

print('Normal for loop:')
for i in range(3):
    print(i)

print('List comprehension:')
[print(i) for i in range(3)]

Normal for loop:
0
1
2
List comprehension:
0
1
2

你也可以在list comprehension裡使用if,如下:

[print(f'{i} 我大於0') if i > 0 else print(f'{i} 我不大於0') for i in range(-5,5)]

-5 我不大於0
-4 我不大於0
-3 我不大於0
-2 我不大於0
-1 我不大於0
0 我不大於0
1 我大於0
2 我大於0
3 我大於0
4 我大於0

最常使用list comprehension的情況是用在要快速篩選清單的時候,例如要得到0~10中的奇數,如下:

oddnumbers = [i for i in range(10) if i%2 == 1]
print(oddnumbers)

[1, 3, 5, 7, 9]

當要使用上面這種情況時,if要放到後面,不然會出現語法錯誤喔!

Bonus Tip 2: 在for迴圈中使用enumerate, zip

如果運行for迴圈時,同時需要清單的物件與index時,可以使用enumerate。

使用方式如下:

weekday = ['禮拜一', '禮拜二', '禮拜三', '禮拜四', '禮拜五', '禮拜六', '禮拜天']

for i, day in enumerate(weekday):
    print(i)
    print(day)

0
禮拜一
1
禮拜二
2
禮拜三
3
禮拜四
4
禮拜五
5
禮拜六
6
禮拜天

將weekday的index以i表示,物件以day表示,然後逐一print出來。

如果要將多個清單的物單,放在for迴圈執行時,可以使用zip。

如下:

weekday = ['禮拜一', '禮拜二', '禮拜三', '禮拜四', '禮拜五', '禮拜六', '禮拜天']
weekday_en = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

print('英文小教室:')
for day, day_en in zip(weekday, weekday_en):
    print(f'  {day}的英文是{day_en}唷!')

英文小教室:
禮拜一的英文是Monday唷!
禮拜二的英文是Tuesday唷!
禮拜三的英文是Wednesday唷!
禮拜四的英文是Thursday唷!
禮拜五的英文是Friday唷!
禮拜六的英文是Saturday唷!
禮拜天的英文是Sunday唷!

總結

以上就是python的迴圈與流程控制,雖然我很簡短的一個文章介紹過去,但實際上每次當你打開IDE開始編寫python的程式時,你都必須使用這些東西,非常大量地使用,如果用得恰當,可以讓你的迴圈少去執行很多不必要的動作,又或者避免之後潛在的錯誤發生,大概就是這樣~

一樣,感謝您閱讀到這裡,希望這篇教學對你有所幫助,我們下回見~

Bye~Bye~

python新手教學
Why python
Hello Python!
This is a python - 基本數值運算與邏輯判斷
[Python, 的, list, 教學 ]
"python的字串教學"
python的迴圈與流程控制
python的(tuple)與{dict}
def 一個python的自訂函數:
import套件到你的python
python的嘗試try與錯誤error處理
Python之禪

相關文章:

>