跳到主要內容

[2021 IT鐵人賽] Day 12:Python基本介紹05 | 流程控制、迴圈

各位安安,今天講的是對任何程式語言都很重要也很基礎的流程控制迴圈的概念,如果你先前已經學過其他程式語言了,那你一定很快就能學起來,如果你之前沒學過也沒關係,今天學完後以後在學其他程式語言時也可以受惠。

流程控制

想像你每天出門時,會依照條件決定要不要帶傘,你的條件是:

如果今天下雨機率大於80%,我出門就帶傘。

則轉換成程式碼後就會是…

rain_prob = 90    # 表示下雨機率

if rain_prob > 80:
    print("出門要帶傘!")

這裡因為下雨機率的確大於80,所以程式會提醒你要帶傘! (這裡我用print()來表示行動)。

但如果下雨機率小於80呢,假如你將下雨機率改為70,你會發現程式什麼東西都沒有印,那原因就是因為我們沒告訴程式條件不成立時該怎麼做。

所以要將上面程式碼稍作修改…

rain_prob = 70

if rain_prob > 80:
    print("出門要帶傘!")
else:
    print("不用帶傘了~")

這是人類和程式的邏輯很不一樣的地方,我們會很下意識地認為說,如果下雨機率沒有大於80,那我們就應該不會帶傘出門。但程式不是這樣,你一定要很清楚地告訴他如果條件不符合時該怎麼做,他才會照著你的意思走。

再來,我們可以加上稍微複雜一點的條件,比方說:

如果今天下雨機率大於80%,而且我不開車上班,我出門就帶傘。

轉換成程式碼後…

rain_prob = 90
drive = True

if rain_prob > 80 and not drive:
    print("出門要帶傘!")
else:
    print("不用帶傘了~")

修但幾累…突然間出現兩個沒看過的關鍵字耶? 別緊張,我們一個個來看。

  • and,連接兩個布林值,如果兩個布林值都是True,and後的結果才是True,否則就是False。
  • not,將布林值反轉,簡單講就是True變成False,False變成True。

順便補充一下or

  • or,連接兩個布林值,如果兩個布林值其中一個為True,or後的結果就是True,否則為False。

整理成真值表後就是底下這樣:

Python的andornot已經算非常直白易懂了,作為比較,在C語言中會對應成&&||!

回到上面例子,雖然說下雨機率大於80沒錯,但因為我要開車的關係,所以最後 True and False 的結果還是False,就不用帶傘了~

然後,我們還可以加上更多的條件:

如果下雨機率大於80,出門要帶傘,但如果下雨機率在60~80間,帶個帽子出門就好了。

等同於下面的程式碼…

rain_prob = 70

if rain_prob > 80:
    print("出門要帶傘!")
else:
    if rain_prob > 60:
        print("帶個帽子就好")
    else:
        print("都不用帶~")

這是巢狀if的結構,如果第一個條件不成立(下雨機率小於等於80),則驗證下一個條件,如果成立(下雨機率大於60),下雨機率就真的在60~80間,則戴頂帽子就好了!

上方的程式碼還可以再簡化,就寫成…

rain_prob = 70

if rain_prob > 80:
    print("出門要帶傘!")
elif rain_prob > 60:
    print("帶個帽子就好")
else:
    print("都不用帶~")

elifelse if 的縮寫,中文意思上有點 “要不然…” 的含意,也就是上方條件如果不符合時,才會檢查這個條件,如果全部條件都不符合,則執行else中的程式。

跟上面的程式碼的邏輯是一模一樣的,但比較起來行數就少一行,所以盡量能用elif就用elif來簡化你的程式碼。

迴圈

迴圈用於處理重複性高的工作,可幫助你省下許多程式碼。

for迴圈

假如我現在想要印出1~10,那我會這樣寫:

for i in range(1, 11):
    print("i =", i)

執行結果:

i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10

我們來看看for迴圈做了什麼事。

首先這個range(1, 11)事實上是個產生器(generator),但如果要講產生器是什麼,就可以花掉一天了XD,想了解產生器的話可以看我之前寫的這篇或別人寫的這篇也滿推薦的。

我們這邊就從簡,當作他是一個從1到10的List,就像這樣:[1, 2, 3, ..., 10]

接著for迴圈就從頭開始(1),一次取一個元素,取完後往前+1,這樣一次稱為一個迭代,就這樣重複執行,直到List結束(10)。

還記得昨天和前天教的容器(Collection)嗎? 他們其實都是可迭代的,也就是說,都可以透過for迴圈走訪一個個的元素。

mylist = ["A", "B", "C", "D", "E"]

for elem in mylist:
    print(elem)

執行結果:

A
B
C
D
E

也可以在for迴圈中放入for迴圈,這稱之為巢狀for迴圈。

使用巢狀for迴圈就可以輕易地印出九九乘法表了!

for i in range(1, 10):
    for j in range(1, 10):
        print("{} * {} = {:2d}, ".format(i, j, i*j), end="")
    print()

結果:

1 * 1 =  1, 1 * 2 =  2, 1 * 3 =  3, 1 * 4 =  4, 1 * 5 =  5, 1 * 6 =  6, 1 * 7 =  7, 1 * 8 =  8, 1 * 9 =  9, 
2 * 1 =  2, 2 * 2 =  4, 2 * 3 =  6, 2 * 4 =  8, 2 * 5 = 10, 2 * 6 = 12, 2 * 7 = 14, 2 * 8 = 16, 2 * 9 = 18,
3 * 1 =  3, 3 * 2 =  6, 3 * 3 =  9, 3 * 4 = 12, 3 * 5 = 15, 3 * 6 = 18, 3 * 7 = 21, 3 * 8 = 24, 3 * 9 = 27,
4 * 1 =  4, 4 * 2 =  8, 4 * 3 = 12, 4 * 4 = 16, 4 * 5 = 20, 4 * 6 = 24, 4 * 7 = 28, 4 * 8 = 32, 4 * 9 = 36,
5 * 1 =  5, 5 * 2 = 10, 5 * 3 = 15, 5 * 4 = 20, 5 * 5 = 25, 5 * 6 = 30, 5 * 7 = 35, 5 * 8 = 40, 5 * 9 = 45,
6 * 1 =  6, 6 * 2 = 12, 6 * 3 = 18, 6 * 4 = 24, 6 * 5 = 30, 6 * 6 = 36, 6 * 7 = 42, 6 * 8 = 48, 6 * 9 = 54,
7 * 1 =  7, 7 * 2 = 14, 7 * 3 = 21, 7 * 4 = 28, 7 * 5 = 35, 7 * 6 = 42, 7 * 7 = 49, 7 * 8 = 56, 7 * 9 = 63,
8 * 1 =  8, 8 * 2 = 16, 8 * 3 = 24, 8 * 4 = 32, 8 * 5 = 40, 8 * 6 = 48, 8 * 7 = 56, 8 * 8 = 64, 8 * 9 = 72,
9 * 1 =  9, 9 * 2 = 18, 9 * 3 = 27, 9 * 4 = 36, 9 * 5 = 45, 9 * 6 = 54, 9 * 7 = 63, 9 * 8 = 72, 9 * 9 = 81,

while迴圈

while迴圈和for迴圈不同點在於,while迴圈沒有給定一個明確的範圍。while迴圈會一直執行直到條件變為False或遇到break。

剛才數1到10的while迴圈版本:

i = 1
while i < 11:
    print("i =", i)
    i += 1

i一開始是1,所以i < 11這個條件是True,因此迴圈會執行print()和i+=1,但是執行到第10次時,i+=1後i就變11了,就不滿足i < 11了阿,所以就會跳出迴圈,結束程式。

除此之外也可以用break跳出迴圈:

i = 1
while True:
    if i > 10:
        break
    print("i =", i)
    i += 1

就如同上一個while迴圈,當i=11時,因為滿足i > 10的條件,所以會執行break,跳出迴圈。

小結

今天教了寫程式中,很基礎卻也很重要的條件控制(if…else…)和迴圈(for、while),以我寫程式的經驗來看,百分之七十的程式碼都是由這些組成的,就可以得知這兩個的觀念有多重要的吧!

因為篇幅有限,只能讓你快速的對Python的語法有個了解,還有很多觀念都沒有講到,所以如果你是初學程式者的話(就是連條件控制和迴圈的觀念都沒有的話),其實我是不太建議你看我的文章學(怕誤人子弟),可以改看其他基礎程式教學,到Google搜尋就有很多囉~ 或許我之後也會再出基礎教學的系列 (先立Flag?

畢竟我是資工系本系,又是從C語言開始學程式的,對if和for這種東西早就用到比呼吸還自然了,一時間要寫文章還真不知道要怎麼講解XD,我已經盡量用最簡單的方式去解釋了,希望能讓在座各位聽得懂,如果有不懂或覺得怎樣寫會更好的,都歡迎在底下留言哦!

明天就是Python基本介紹的最後一天了! 我將介紹函數、讀寫檔案、引用的觀念,那麼,我們明天見(๑•̀ㅁ•́๑)✧


如果喜歡這系列文章麻煩幫我按Like加訂閱,你的支持是我創作最大的動力~

本系列文章以及範例程式碼都同步更新在GitHub上,後續會持續的更新,如果喜歡也麻煩幫我按個星星吧~

有任何問題或建議,都歡迎在底下留言區提出,還請大家多多指教。


如果喜歡這篇文章,請訂閱我並且拍五下手給予回饋(使用Google或Facebook帳號免費登入,只需要30秒),資金由LikeCoin提供,完全不會花到各位半毛錢!

因為您的支持,我才更有動力創作出更優質的文章~

留言

這個網誌中的熱門文章

[遊記] 2022/07/22 南寮漁港、香山濕地

前言: 2022年的暑假,我來到新竹的工研院實習,因此有了兩個月好好探索這座陌生城市的機會。我在來之前就計畫好了,每周五要選一個地方去旅行,目標是在兩個月內把整個新竹玩透透! 來到了第三個禮拜,今天我約了新竹在地人的大學朋友,請他騎機車載我到處逛逛😆 不過因為他早上有事情,所以我們就約中午吃飯。中午我們去吃城隍廟附近的 阿桂羊牛雜 ,我點了朋友很推的 羊肉炒麵 ,這家的炒麵很特別,醬汁很濃稠,沙茶味很香~ 我點加辣但有點太辣了,下次可能點小辣就好。另外有附飲料和冷氣這點很加分。 (只顧跟朋友聊天,就忘記拍照了😂) 阿桂羊牛雜 羊肉炒麵 $100 推薦指數:4⭐ 吃完飯後,本來想去南寮漁港,但因為今天的太陽真的太大了! 所以朋友就提議先去 新竹巨城 吹冷氣,晚點再去南寮漁港。雖然已經來過巨城一次,但跟別人一起逛就是不太一樣。我們去逛了服飾店、書局和湯姆熊,不知不覺就三點了。於是就離開巨城前往南寮漁港囉~ 本來以為 南寮漁港 很遠,但騎機車一下子就到了,果然在新竹還是要有機車比較方便阿! 我們先去南寮漁港的遊客中心,展望台的景色很不錯,室內還有溜滑梯可以玩呢! 接著我們在附近的魚市場、國際風箏場等地方邊聊邊走,最後走到 魚鱗天梯 。 魚鱗天梯看起來的確很像魚鱗,但聽說他的功能其實是消波塊,還真酷! 底下就有一小片沙灘,因為我今天穿拖鞋,就有下去踩一下海水。不過這裡的海水沒很乾淨,上來後腳上全都是沙子,幸好旁邊就有可以洗腳的地方。 其實旁邊有個滿有名的 17公里海岸自行車道 ,不過我們比較晚才到,所以就沒租腳踏車去騎了。 接著就往南到 香山濕地 ,騎機車也是一下就到了。 香山濕地就像小型的高美濕地,一旁的 賞蟹步道 可以直接走在溼地上方。 賞蟹步道兩旁真的很多螃蟹,照片裡的白點都是螃蟹哦! 當時剛好碰上漲潮,於是我們就在步道上拍起縮時攝影,從影片中可見漲潮的速度有多快! 香山濕地也是看夕陽的好景點,只是有點太早來了,於是我們走去旁邊的 綠色隧道 ,等待夕陽下山。 最後終於等到夕陽了! 加上倒影還滿漂亮的,只可惜今天海面有點雲,無緣看到夕陽落到海平面之下的景色。 最後順路繞去附近的 青青草原 ,雖然天色已經暗了下來,不過因此溜滑梯都不用排隊,可以多溜了幾趟😁 我們也去看了一眼大草原,但因為傍晚有一堆蚊蟲,所以就趕緊撤退了! 最後晚餐去吃 蛋包飯 ,這家也是朋友推薦的...

[Python] async def & await 重點整理

最近實習要用到 FastAPI ,我發現 FastAPI 的 path operation function 會使用 async def ,還會搭配使用 await ,因為對這兩個關鍵字沒很熟,所以就藉機紀錄一下,也避免之後忘記。 async def & await 使用情境 我直接利用下面這個例子來展示什麼情況下可以使用 async 和 await 。 import time def dosomething ( i ): print ( f"第 {i} 次開始" ) time.sleep( 2 ) print ( f"第 {i} 次結束" ) if __name__ == "__main__" : start = time.time() for i in range ( 5 ): dosomething(i+ 1 ) print ( f"time: {time.time() - start} (s)" ) 執行後應該會像這樣。 第 1 次開始 第 1 次結束 第 2 次開始 第 2 次結束 第 3 次開始 第 3 次結束 第 4 次開始 第 4 次結束 第 5 次開始 第 5 次結束 time: 10.048049688339233 (s) 這非常直覺,因為每次呼叫 dosomething() 時都會等待2秒,等完才會執行下一輪,所以最後執行總時間是10秒相當合理。 但仔細想想,如果那2秒是做網路請求或檔案讀寫(IO),這2秒是不需要CPU的,但CPU就只能發呆2秒,痴痴地等待回傳結果,其他什麼事都不能做,豈不是太浪費了嗎!? (學過作業系統的人就知道,絕對不能讓CPU發呆XD) 因此 Python 就有了 asyncio 這個工具,來徹底的利用(X) 榨乾(O) CPU的效能。 我把剛才的例子改成 asyncio 的版本。 import time import asy...

[2021 IT鐵人賽] Day 23:專案05 - KKBOX風雲榜02 | AJAX

昨天已經找到的KKBOX用來傳資料的API,也知道各個參數的意義了,今天就實際將資料抓下來吧! 歌曲資訊 回到昨天那個API,是用JSON格式傳遞資料,資料的格式大致如下: 我們可以發現新歌的資料都放在 “newrelease” 之下,一個element就是一首歌的資訊,另外,每首歌的資訊也以key:value的形式整理的很清楚。 接著,就用之前教過的 requests.get(url) 直接取得API回傳的資料,但回傳的型態是json字串,所以再用Python本身內建的 json.loads() 函數轉成Python的list和dict資料型態。 # KKBOX華語新歌日榜 url = "https://kma.kkbox.com/charts/api/v1/daily?category=297&lang=tc&limit=50&terr=tw&type=newrelease" # 取得歌曲資訊json檔 response = requests.get(url) # 將json字串轉為Python的字典型態 data = json.loads(response.text) 既然已經轉成list和dict的型態了,再根據剛才觀察API得知的架構,要篩選資料就非常簡單,直接來看程式碼: song_list = data[ "data" ][ "charts" ][ "newrelease" ] # 取得每首歌的排名、曲名、連結、作者、時間 for song in song_list: song_rank = song[ "rankings" ][ "this_period" ] song_name = song[ "song_name" ] song_url = song[ "song_url" ] song_artist = song[ "artist_name"...