###### tags: `社團事務`
# ✔ Python 從入門到放棄

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
- 跳脫字元

+ **複數**: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 位元下去計算喔!
### 優先順序
正如同數學上的 先乘除後加減,有括號先算 ,運算子之中也是有分順序級數ㄉ,在程式運行的時候需多加留意。

## 🎊 條件選擇
### 概念
當程式碼運行到某些地方時,如果需要加些條件選擇性執行程式碼,就會需要用到這種好用的東西。
如果我們將其細分,此語法結構可分為 2 個部分:**條件** 以及 **敘述句( 該做甚麼事 )**
而 **條件** 裡我們可以運用 **條件運算子** 和 **邏輯運算子** 以達成我們的目的
### 真值表
判斷 **True**、**False** 的規則,可參考邏輯運算子的定義

### **if-else 條件句**
+ 圖示

+ 結構
```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)
```
### 遞迴
**遞迴**就是自己呼叫自己,與數學上的遞迴關係式很像。
我們拿費氏數列作舉例:
數學上遞迴關係式:

程式上:
```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 時的費波那契數列為例,他在進行函式執行時的呼叫順序如下:

將其拆項,看他一步一步的步驟就會這樣:
>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'))()
```