###### tags: `社團事務` # ✔ Python 從入門到放棄 ![](https://i.imgur.com/RKUaLop.png) Python 是目前世界上最廣泛使用的程式語言之一,也是對程式新手來說一大福音,簡單易懂、規格整齊、功能大致齊全,新手也可以在其[官網](https://www.python.org/)上找許多資源。 ## 🎨 選擇編譯器(Editor) 基本上入門學習使用任何編譯器都可,但是長久來說選擇編譯器也是一門學問 推薦的編譯器有 + Code Blocks : APCS指定編譯器之一,但寫Python會有點麻煩。 + Dev C++ : 不會更新的編譯器 + VS code : 功能齊全,設置不難,推 + VS : 超肥,功能超級齊全,但基本上不用那麼高級也不會怎樣 + Xcode : mac仔才有的東西,但據說挺垃圾的 + sublime : 電神用爆,但是這個是 Text Editor 並沒有 debug 功能喔 + spyder : python專用 最後溫馨提醒,記得用**暗色主題** ## 連結 + [社團官網](tcirc.tw) + [TcfshJudge](judge.tcirc.tw) + [社課範例與練習題](https://hackmd.io/@RucKuo/Circ-Python-practice#/) --- ## 👓 輸入及輸出 首先我們先學如何與電腦互動,也就是輸入及輸出 ### 輸出 如果想要**輸出**應該這麼打: ```python print( 欲輸出的東西_1,欲輸出的東西_2... ) ``` + 範例 試試看印出 "Hello, world!" 吧! ```python print( "Hello, world!" ) # 印出 : Hello, world! # 以換行為結尾 print("A", "B", "C") # 印出 : A B C # 中間預設空格隔開 # 以換行為結尾 ``` + 格式化輸出 + 分割輸出與結尾輸出: - **sep** : 用來分隔的字串, 預設為空格 - **end** : 用來結尾的字串 ```python print(要輸出的東西, sep=要用來分隔的字串, end=要用來結尾的字串) print("A", "B", sep="+", end="=0") # 印出 : A+B=0 ``` + **format** ```python print("{0} is {1}".format('Python', "EASY")) ## Python is easy a = "Circ" b = "ddc" print("{} is better than {}".format(a, b)) #Circ is better than ddc ``` + %%% | %d | %s | %f | |:---:|:------:|:-----:| | int | string | float | ```python a = 123 b = "circ" print("%d, %s" %(a, b)) ``` ### 輸入 如果想要**輸入**應該這麼打: ```python 變數名稱 = input() # 預設為字串 變數名稱 = input("請輸入一正整數:") # 輸入的前置訊息 ``` ## 🎹 變數 變數(variable) 簡單來說,就是對一特定值取名字。 變數是箱子,把你想放的東西(**值value**)放進去,可以用變數名稱(箱子的標籤)找到它。 ```python < 變數名稱 > = < 起始值 > a = 10 b = "hello!" ``` ### 變數名稱 變數的取名也是一大藝術,為了增加程式碼的可讀性,我們會將變數名稱盡量使我們看得懂像是speed、sum 等等。 但同時避免使用到程式保留字、特殊字元或其他,例如:for、int、!@$%&+-、0oO1lI 等。 ### 變數型別(Basic data type) 箱子也是有分各種意義的箱子,特定型別、大小的箱子只能裝特定型態、大小的箱子。 變數型別有: + **整數**: int + **浮點數**:float + **布林值**:bool - 判斷是否,True = 1,False = 0 + **字元、字串**:str - 跳脫字元 ![](https://i.imgur.com/PVYO32w.png) + **複數**:complex ### 確認變數型別 ```python # type() 可以幫助我們確認變數型別,例如 print(type(123)) #< class 'int'> print(type(0.123)) #< class 'float'> print(type('123')) #< class 'str'> print(type(True)) #< class 'bool'> print(type(1 + 2j)) #< class 'complex'> ``` ### 字串應用 字串可以看作一串字元,可以想像成把一堆箱子串在一起,規則近似串列。 #### 取其一字元 - 利用 [] 來取出一字串其中一個字元 - 其規則近似串列 | 0 | 1 | 2 | 3 | 4 | 5 | | - | - | - | - | - | - | | p | y | t | h | o | n | - sv[1] 表示第二個字元 - sv[2:4] 表示第三到四個字元 - sv[-1] 表示倒數第一個字元 ```python= sv = "python" print( sv[0] ) # p print( sv[1:5] ) # ytho print( sv[-1] ) #n ``` #### 取得長度 + 可以用``len()``函式來取得一字串的長度 + 會回傳一整數 ```python sv1 = "circ" sv2 = "python" sv3 = "123456789" a = len(sv1) # a = 4 b = len(sv2) # b = 6 c = len(sv3) # c = 9 ``` #### 分割 - 因為我們 OJ 的測資問題,用python解題一定要用到字串分割 - 用 ``split()`` 來分割字串 - 會回傳一串列 - ()內是用來分割的字元 ```python sv = "python is easy" lv = sv.split(" ") # lv 為一陣列 其值爲 {"python", "is", "easy"} a = sv.split(" ")[0] # a 為一字串 其值爲 "python" b = sv.split(" ")[1] # b 為一字串 其值爲 "is" c = sv.split(" ")[2] # c 為一字串 其值爲 "easy" sv2 = "python:is:easy" lv1 = sv2.split(":") # lv 為一陣列 其值爲 {"python", "is", "easy"} ``` ### 型別轉換 當對一個數作運算時,變數之型態會隨需求轉換 + 進行強制轉換格式(**短暫**): ```python a = 3.14 int(a) # <預轉換型別>(變數) ``` + **int()** ``` python= a = '123456' b = int(b) print(b) # 印出:123456 print(type(b)) # 印出:<class 'int'> ``` + **str()** ``` python= a = 2156 c = str(a) print(c) # 印出:2156 print(type(c)) # 印出:<class 'str'> ``` + **round()** ```python= round( x [, n] ) # round()方法返回 x 的小數點四捨五入到 n 個數字。 a = 3.1415926 print(round(a)) # 印出:3 print(round(a,2)) # 印出:3.14 print(round(a,4)) # 印出:3.1416 ``` + **abs()** ``` python= a = -45 print(abs(a)) # 印出:45(-45 的絕對值) ``` ### 變數使用範圍 + **全域變數( global )** 宣告在函式外的變數,可在所有接下來程式讀取的地方使用 ```python 函式 A global a = 3 函式 B 函式 C 主函式 ``` + **區域變數( local )** 宣告在 **某一縮排內的變數**,可以在接下來所有小於等於縮排序的地方使用 ```python 縮排序 1 縮排序 2 a = 'hello' 縮排序 3 #可使用 a #可使用 a #不可使用 a ``` ## ✨ 運算子 聽起來很專業的名字,但其實你們都學過,下面我們來看看有那些ㄅ ### 算術運算子 簡單來說,加減乘除餘而已啦! ```python 7 + 4 = 11 # 加號 + 7 - 4 = 3 # 減號 - 7 * 4 = 28 # 乘號 * 7 / 4 = 1.75 # 除號 / 7 // 4 = 1 # 取商 // 7 % 4 = 3 # 餘號 % 7 ** 4 = 2401 # 次方 ** ``` ### 指派運算子 好酷的名字,但是新手最大的噩夢,認真看好囉! ```python a = 1 # 指派(assign),將右值指派給左邊的值 a += 10 # 等於 a = a + 10 a -= 10 # 等於 a = a - 10 a *= 10 # 等於 a = a * 10 a /= 10 # 等於 a = a / 10 a //= 10 # 等於 a = a // 10 a %= 10 # 等於 a = a % 10 ``` ### 關係運算子 以確認關係(比較)為用途的運算子~ ```python a == 10 # 真正數學意義上的等於(equal),常與 assign 搞混,多加留意 a != 10 # 不等於 a > 5 # 大於 a < 15 # 小於 a >= 9 # 大於等於 a <= 11 # 小於等於 ``` ### 邏輯運算子 條件式的好幫手,增加判斷邏輯是否正確的條件。 以下介紹: + and:**布林 AND 運算**,當左右 2 個條件皆為 **True** 時,才會回傳 1 + or:**布林 OR 運算**,當左右 2 個條件其中 1 個為 **True**,就會回傳 1 + not :**布林 NOT 運算**,後面的變數 **True** 轉 **False**、**False** 轉 **True** |x|y|and| or| |-|-|:-:|:-:| |1|1| 1 | 1 | |1|0| 0 | 1 | |0|1| 0 | 1 | |0|0| 0 | 0 | ```python num = 75 print(num > 70 and num < 80) # 輸出 1 ( True ) print(num > 80 or num < 76) # 輸出 0 ( False) print(not(num > 80 or num < 75)) # 輸出 1 ( True ) print(num > 80 or not num < 75) # 輸出 0 ( False ) ``` ### 位元運算子 挖,抽象的概念來了,首先我們要知道電腦是以 1 與 0 所構成,將每個數字、字元等等轉變成所謂的 **2 進位**( binary )。 例如: 10 => 00001010 18 => 00010010 好了大家繫上安全帶,準備飆車囉! + **左移運算子**:將 01數字串 全部往左 n 格,多的被擠掉,空的補 0。 ```python a = 10 # 00001010 a << 2 # 00101000 ``` + **右移運算子**:將 01數字串 全部往右 n 格,多的被擠掉,空的補 0。 ```python a = 10 # 00001010 a >> 1 # 00000101 ``` + **AND 運算(&)**:若兩數皆為 1 則輸出是 1,其餘狀況輸出皆為 0 ```python foo = 147 ; # 10010011 bar = 2 ; # 00000010 int(foo & bar) # 00000010 ``` + **OR 運算(|)**:若兩數只要有 1 則輸出 1,其餘狀況輸出皆為 0 ```python foo = 147 # 10010011 bar = 2 # 00000010 int(foo | bar) # 10010011 ``` + **XOR 運算(^)**:若兩數不同( 1、0 ) 則輸出是 1,其餘狀況輸出皆為 0 ```python foo = 147 # 10010011 bar = 2 # 00000010 int(foo ^ bar) # 10010001 ``` **值得注意**:其實就算範例都取 8 位元的 01數字串 ,實際計算得依照型態作改變。 假如我使用 int 儲存該變數,應該有 4 位元組,也就是 32 位元下去計算喔! ### 優先順序 正如同數學上的 先乘除後加減,有括號先算 ,運算子之中也是有分順序級數ㄉ,在程式運行的時候需多加留意。 ![](https://i.imgur.com/UXsxSMP.png) ## 🎊 條件選擇 ### 概念 當程式碼運行到某些地方時,如果需要加些條件選擇性執行程式碼,就會需要用到這種好用的東西。 如果我們將其細分,此語法結構可分為 2 個部分:**條件** 以及 **敘述句( 該做甚麼事 )** 而 **條件** 裡我們可以運用 **條件運算子** 和 **邏輯運算子** 以達成我們的目的 ### 真值表 判斷 **True**、**False** 的規則,可參考邏輯運算子的定義 ![](https://i.imgur.com/Q22i3zY.png) ### **if-else 條件句** + 圖示 ![](https://i.imgur.com/Lfn6ktp.png) + 結構 ```python if 第一條件句 : # 縮排(tab) 該做甚麼事 elif 第二條件句 : 該做甚麼事_2 elif 第三條件句 : #elif 是 else if 的縮寫 該做甚麼事_3 . . . else : 剩下的該做甚麼事 ``` ### 三元運算子 可以看做比較簡潔的if-else判斷句,當if-else判斷句內要做的事情較少時可以考慮使用 ``<條件為 True 時做的事> if <判斷句> else <條件為 False 時的做的事>`` ```python a = int(input()) print("偶數" if a % 2 == 0 else"奇數") ``` ### 巢狀 if 也就是將 if 條件句包在另一 if 條件句之內 ```python if 條件句_1: 做甚麼事 if 條件句_2: 做甚麼事 做甚麼事 ``` ### **try-except 條件格** 此為 python 中較特別的功能,可以將一個區塊之程式碼先執行看看,如果發生**例外事件**就會**引發**( Raise )程式執行另一區域。 至於為什麼要這樣,是因為 Python 是**直譯語言**,所以會以發起例外 (exception) 的方式來中斷程式的執行。實際上,很多情況下我們需要自行控制可能會產生例外的程式碼,因為**例外並不全然是程式的邏輯錯誤**,例如程式中打算開啟檔案,然而實際檔名並不存在,這種情況下,我們需要的是例外發生後的處理動作,而非中止程式的執行。 + 結構 ```python try: 內容 except (錯誤內容): 內容 ``` + 舉例 ```python try: input = int(input('輸入整數:')) print('{0} 為 {1}'.format(input, '奇數' if input % 2 else '偶數')) except ValueError: print('請輸入阿拉伯數字') # 如果使用者輸入的不是整數,就會出現錯誤,然後跳到 except 區塊內 ``` + **else** 及 **finally** 的搭配 ```python try: statement except some: statement except: statement else: statement finally: statement ``` - **else** : 如果 try 區塊中沒有任何的錯誤發生,則會執行 else 區塊 - **finally** : finally 區塊一定會執行,這通常用來作為關閉若干資源的區塊,例如關閉檔案 ## 🎡 迴圈控制 ### 概念 **迴圈**( loop )就是將同一件事重複執行 n 次, 而我們可以將迴圈細分成: 1. **起始值** 1. **間距** 1. **結束值** 2. **內容** ### **for 迴圈** **for 迴圈** 為較易理解之迴圈,結構完整但語法需記住,是初學者常忘記的一個難關。 不過,其實 **for 迴圈**有許多變形,此型為最基礎,詳細內容之後會介紹~ + 結構 ```python for 變數名 in range(起始值,結束值,間距) #在range的地方可以改放串列 內容 ``` + 範例: ```python for i in range(1,10): print("Hello, world!") ``` + **range() 函式** **range()** 函数可創建一个整數列表,一般用在 for 循還中。 ```python range([start,] stop[, step]) # start : 起始值,預設為 0 # stop : 停止值,一定要寫 # step : 間距值,預設為 1 range(10) # 0 1 2 3 ... 9 range(1,10) # 1 2 3 4 ... 9 range(1,10,2) # 1 3 5 7 9 ``` + **巢狀for迴圈** 就是將一個 **for** 包在另一個 **for** 裡 ```python for 變數 in 範圍1: # 範圍1的值用完前要一直做的事 for 變數 in 範圍2: # 範圍2的值用完前要一直做的事 # 範圍1的值用完前要一直做的事 # 其他程式碼 ``` ### **while 迴圈** **while 迴圈** 較為注重結束條件,寫不出 for 迴圈 時,可以試著用 while 迴圈 解 + 結構 ```python 起始值宣告 while 針對起始值變化執行條件 : 內 容 ``` + 範例: ```python= i = 0 while i < 10: print("Hello, world!") i += 1 ``` ### 相關功能 + **break** **break** 可以**離開**目前 for、while 等區塊,並前至區塊後下一個陳述句。 ```python= for i in range(1,10) : if i == 8: # i 值為 8 時脫離迴圈執行下一陳述句 break print("Hello, world!") print("Break the loop!") # 脫離迴圈完執行 ``` + **continue** **continue** 會結束接下來區塊中的陳述句,並跳回迴圈開頭**繼續**下一個迴圈。 ```python= for i in range(1,10): if i == 8: continue # i 值為 8 時直接跳到 step 的部分,執行下一輪迴圈。 print("Hello, world!") ``` ### 無限迴圈 - 通常用於不確定迴圈次數時 - 用 try-except 判斷句來結束迴圈 ```python= while True: try: a = int(input("請輸入數字")) except: print("非數字") break print(a) ``` ## 🚌 串列 ### 概念 **串列**( list )可以將 **不同或同一型別** 且 **一連串無或有關聯** 的變數儲存的一系列記憶體。 串列自由度高,使用前不需要先指定使用空間,若需要變動,則可以利用多種函式達到此一效果。 最後要講一個超級重點,所有關於 list 的**索引值**( index )都是**從 0 開始**: | Index | 0 | 1 | 2 | 3 | 4 | | -------- |:--------:|:--------:|:--------:|:---:|:---: | | Element | 10 | 20 | 30 | 40 | 50 | ### 一維串列 如前言所述, 串列是變數在連續的記憶體上併排在一起的東西。而一維串列就是只有一個維度的串列,宣告一維串列的方法如下: #### 宣告 ```python= # 空串列宣告 demo_1 = [] demo_2 = list() # 連同初始值一起宣告 # <串列名稱> = [元素_1,元素_2,元素_3...] a = [ 1, 3, 5, 7] b = [37, "CIRC", True] #串列可以放不同型態的東西 #可以直接輸出串列 print(a) print(b) ``` ### 功能 + .append(value) - 在串列尾端加入元素 + .insert(index,value) - 在該索引值加入元素 - 索引值之原元素與後方元素往後推移 + .extend(list) + 將一串列(括號內串列)之元素加入另一串列(`.`前串列)之尾端 + .remove(value) + 移除串列中該元素 + 若有多個會移除索引值最小的 + .pop([index]) + 移除串列中該索引值之元素並回傳該元素 + 預設值爲尾端 + len(list) + 取得該串列之長度 + .index(value) + 取得該元素第一次出現的索引值 + .count(value,[start_index],[end_index]) + 取得該元素在串列中出現次數 + 起始索引值預設為0 + 結束索引值預設為該串列之結尾 + sum(value) + 取得該串列元素之總和 + .sort + 排列該串列 + .reverse() + 反轉該串列 + in + 檢查該元素是否在該串列中 + 會回傳一布林值 + 有該元素回傳 True + 沒該元素回傳 False + 用法︰`<元素> in <串列>` + not in + 檢查該元素是否**不**在該串列中 + 會回傳一布林值 + 有該元素回傳 False + 沒該元素回傳 True + 用法︰`<元素> not in <串列>` + max(list) + 取得該串列中元素的最大值 + min(list) + 取得該串列中元素的最小值 ### 串列應用 + 取值 當要存取一維串列的值時,可以使用運算子[]和索引來存取特定的元素。 ```python= a = [ 2, 4, 6, 8] print(a[0]) # 印出 2 print(a[1]) # 印出 4 print(a[2]) # 印出 6 print(a[3]) # 印出 8 print(a[-1]) # 印出 8 print(a[-2]) # 印出 6 print(a[-3]) # 印出 4 print(a[-4]) # 印出 2 ``` + 輸入 ```python # 假設輸入 5 個元素 lv = [] for i in range(0,5,1) a = input() lv.append(a) ``` + 輸出 ```python a = [ 2, 4, 6, 8] print(a) #直接輸出串列 lengh = len(a) # 取得 a 串列長度 for i in range(lengh) print(a[i]) # for ㄉ條件裡也可以放串列 #只有當串列中元素為整數時可用 for j in a: print(j) # 以上範例中 **i** 值跟 **j** 值是不同的喔。 # i 值為 0 1 2 3 ,為串列中的 index 值 # j 值為 2 4 6 8 ,為串列中的 value 值 ``` :::danger **應該注意**:如果使用超過串列長度的索引值,會發生不可預期的結果。 ::: + 運算 沒錯,**list** 也可以運算耶,這就是 python 強大的地方 ```python a = [1, 2, 3, 4] b = [5, 6, 7, 8] c = a + b # c = [1,2,3,4,5,6,7,8] d = a * 2 # d = [1,2,3,4,1,2,3,4] ``` ### 二維、多維串列 上面的 一維串列若將其視為一條線( **X 軸** ), 二維串列則可視為一個面( **X、Y軸** )、 三維則是一個體( **X、Y、Z軸** ), 而更高維的就因超出我們的理解範圍,所以我們也較少用。 但其實二維串列也可看做矩陣 不過,在任何程式語言中其實沒有所謂的多維串列,所謂的串列不過是**串列中的串列**罷了。 + **二維串列** 此陣列主要用於有 2 組數字與你所需要存取的對象有關聯, 如:幾班幾號的**數學成績**、幾月幾日的**體重**等等。 這裡假設有兩班、一班四人,串列存放值爲該學生成績 - **宣告** ```python # 第一種宣告法︰排成一排 l1 = [[100,80,60,40],[100,80,60,40]] # 第二種宣告法︰依縮排排列,結束符號在最後 l2 = [ [100,80,60,40], [100,80,60,40]] # 第三種宣告法︰依縮排排列,結束符號在新行最左 l3 = [ [100,80,60,40], [100,80,60,40], # 記得在最後一組串列後加逗號 ] ``` + **多維串列** 也可以宣告三維串列與三維以上的串列。 例如: ```python arr3 = [[[]]] # 三維陣列 arr4 = [[[[]]]] # 四維陣列 ``` 但超過四維就比較難以想像,因此一般較少使用。 ## 📕字典 字典(dictionary)就像一本正常的字典一樣,一個字詞(KEY)對應到一個意思(Value)。 它的每一組資料都包含一個關鍵字與一個值。 ### 宣告 ```python d1 = {} #用大括號宣告 d2 = dict() #用 dict() 函式宣告 ``` 字典中的資料為一個關鍵字對應到一個值,如:``key : value`` 用冒號來分個關鍵字與值,用逗號分個資料 ``{key1 : value1, key2 : value2, ....}`` 舉個例子,用一個字典儲存一個人的資料 ```python= Alice = {'name' : 'Alice', 'age' : 18, 'nationality' : 'Taiwan'} ``` ### 取得資料 #### [] 可以用方括號來取得對應的值 ```python Alice = {'name' : 'Alice', 'age' : 18, 'nationality' : 'Taiwan'} print(Alice['name']) #會輸出 'Alice' #若 key值為字串應加上引號 ``` 欲取得資料不存在時,用方括號的話程式會直接報錯,若要解決這個狀況可用 .get() 函式 #### get() 可以用``.get()``函式來取得字典中的資料 get函式包含兩個值 ``` dictname.get(<key值>,<key值不存在時的回傳值>) #key值不存在的回傳值預設為 None ``` ※沿用上面 Alice 的資料 ``` print(Alice.get('name')) #輸出 'Alice' print(Alice.get('school', 'Not Found')) #輸出 'Not Found' ``` ### 加入、更改資料 #### [] 用方括號可更改資料或新增資料 ```python Alice['age'] = 17 #更改 age 為 17 Alice['school'] = 'tcgs' ##新增資料 school : tcgs ``` #### update() 在一字典中新增另一字典的值 ```python= Alice = {'name' : 'Alice', 'age' : 18, 'nationality' : 'Taiwan'} alice = {'school' : 'tcgs', 'relationship status': 'Single'} Alice.update(alice) Alice.update({'favorate_food' : 'chocolate'}) ``` ### 刪除資料 #### del ```python= del dictname[key] ``` #### pop ```python= dictname.pop(key) ``` ```python= Alice = {'name' : 'Alice', 'age' : 18, 'nationality' : 'Taiwan'} del Alice['age'] Alice.pop('nationality') ``` ### 輸出資料 ```python= Alice = {'name' : 'Alice', 'age' : 18, 'nationality' : 'Taiwan'} print(Alice) #輸出所有資料 print(Alice.items()) #輸出所有資料 print(Alice.keys()) #輸出所有key值 print(Alice.values()) #輸出所有value值 ``` 執行結果 ``` dict_keys(['name', 'age', 'nationality']) dict_values(['Alice', 18, 'Taiwan']) dict_items([('name', 'Alice'), ('age', 18), ('nationality', 'Taiwan')]) ``` ### 有序 v.s 無序 有序容器內的資料會依照順序排列;無序容器內的資料會按照特定方式排列而非指定順序。 list 是一個有序容器,其儲存的資料會按照程式插入的順序排列 dict 是一個無序容器,其儲存的資料會依照 key值排序 ```python= l1 = [1, 2, 3, 4] l2 = [1, 2, 4, 3] l1 == l2 #False d1 = {1:1, 2:2, 3:3} d2 = {1:1, 3:3, 2:2} d1 == d2 #True ``` ## 🛹 函式 ### 概念 簡單來說,**函式**就是外包給其他地方加工啦,而且可以順便達到簡化跟美化程式碼的功能。 函式中最注重的就是在於參數之中的傳遞,而且盡量將函示放置在主函式前,這樣一來,不僅不會破壞程式的結構,還能增加程式的可讀性。 ### 架構 ```python def <函式名稱>(參數 A, 參數 B) 內容 return [回傳值] ``` ### 函示傳遞 傳遞是函式中最重要的環節。 將一個值傳遞給函式做,稱為**參數**; 函式執行完傳遞回來的值,稱為**回傳值**。 假如需要回傳時,使用 **return** 幫助傳回。 我們以2數相加為舉例: ```python= def add(a, b): c = a + b return c # c 為回傳值, m, n = 2, 4 result = add(m,n) print(result) ``` ### 遞迴 **遞迴**就是自己呼叫自己,與數學上的遞迴關係式很像。 我們拿費氏數列作舉例: 數學上遞迴關係式: ![](https://i.imgur.com/jdq1nJl.png) 程式上: ```python int F(n) if(n == 0): return 0 else if(n == 1): return 1 else: return F(n-1) + F(n-2) ``` 若我們以計算 n=5 時的費波那契數列為例,他在進行函式執行時的呼叫順序如下: ![](https://i.imgur.com/lu8tYSZ.jpg) 將其拆項,看他一步一步的步驟就會這樣: >1. 主函式傳入 n=5 >2. 進入 else 中,執行 F(4) + F(3),所以呼叫 n=4 與 n=3 >3. 循環 > 4. 一直到某次執行 F(1) + F(0),所以呼叫 n=1 與 n=0 > 5. 分別進入 if 與 else if 中,回傳 1 與 1 > 6. 因此 F(1) + F(0) = 1 + 1 > 7. 循環 > 8. 得到F(4) + F(3) = 5 > 9. F(5) = 5 而我們會發現這個效率不佳,重複呼叫太多次,導致時間複雜度超級高, 所以這時候我們就可以進入到演算法的世界拉 ~ ### 匿名函式 匿名函式(lambda)其實就是比較簡潔的宣告函式的方式。 宣告: ``<函式名稱> = lambda arg1, arg2, arg3,....:expression`` 以定義一個比較兩數大小的函式為例 ```python #用正常宣告函數的方式 def max(a,b): return a if a > b else b #使用匿名函式 max = lambda a, b:a if a > b else b ``` #### switch case 的替代方法 有學過其他語言的人可能會知道 switch case 這個好用的東西, 但 Python 沒有 switch 陳述句 QQ, 但可以透過 lambda 配合 dictionary 來模擬它。 ```python= score = input("你的分數") level = score // 10 { 10 : lambda : print('A'), 9 : lambda : print('B'), 8 : lambda : print('C'), 7 : lambda : print('D'), 6 : lambda : print('E') }.get(level, lambda : print('F'))() ```