I. 函式
A. 何謂函式?
想必大家應該不陌生,在數學科目中應該多少有接觸到吧!!
B. 為何需要函式?
最主要其實是要將某個流程封裝、模組化,未來若需要進行同樣流程時,我們只需要呼叫這模組即可,程式碼能夠精簡化,也比較美觀
人偶爾會幻想如果有個僕人能幫我做牛做馬的那該有多好啊!!其實函式就像是個專業的僕人,你可以請他幫你完成一些事,不過要記住,他是個專業的僕人,不是萬能的僕人,專業的僕人只會做專業的幾件事喔!
C. 函式的基本結構
1. 無回傳值、無參數輸入型
def wash_dish():
print('是!我立刻去洗盤子')
2. 無回傳值、有參數輸入型
def wash_dish(x):
print('是!我立刻去洗',x,'個盤子')
3. 有回傳值、無參數輸入型
def wash_dish():
s = "是!我立刻去洗盤子"
return s
4. 有回傳值、有參數輸入型
def wash_dish(x):
s = "是!我立刻去洗" + str(x) + "個盤子"
return s
D. 函式呼叫
1. 既然函式可以視作僕人,呼叫函式的就是主人囉!
2. 在主人還沒呼叫函式前函式是不會有動作的
3. 函式必須在呼叫前先定義完成
4. 參數可以有多個,且型態不拘
1. 無參數的函式
# 函式必須要先定義,但不會做出動作
def wash_dish():
s = "是!我立刻去洗盤子"
return s
# 主人開始呼叫函式,這時函式才開始動作
print(wash_dish()) # 是!我立刻去洗盤子
2. 單個參數的函式
# 函式必須要先定義,但不會做出動作
def wash_dish(x):
s = "是!我立刻去洗" + str(x) + "個盤子"
return s
# 主人開始呼叫函式,這時函式才開始動作
print(wash_dish(5)) # 是!我立刻去洗5個盤子
3. 多個參數的函式
def add(a, b):
return a + b
x, y = map(int, input("請輸入兩個整數:").split())
print(add(x, y))
主人用x與y參數傳給僕人,僕人方相對應的參數改為a與b。當然,仍沿用x與y名稱也可以
4. 未知個參數的函式
函式中參數前面加上*
號,表示可輸入未知筆資料,所輸入的資料將存在陣列(tuple)中
def make_snow_ice(*toppings):
print('您的雪花冰配料如下:')
for topping in toppings:
print(topping)
make_snow_ice('愛玉') # 您的雪花冰配料如下:愛玉
make_snow_ice('愛玉', '花生', '芋圓') # 您的雪花冰配料如下:愛玉 花生 芋圓
5. 各式型態的參數
# 有預設值的參數
def interest(type, area='Taiwan'):
print('我的興趣是', type, '最喜歡的地方是', area)
interest('吃飯') # 我的興趣是 吃飯 最喜歡的地方是 Taiwan
interest('吃飯', 'New Zealand') # 我的興趣是 吃飯 最喜歡的地方是 New Zealand
interest(area='New Zealand', type='吃飯') # 我的興趣是 吃飯 最喜歡的地方是 New Zealand
# 陣列當參數
def find_max(input_list):
return max(input_list)
num_list = [8, -7, 16, 5, -2]
print(find_max(num_list))
# 浮點數當參數
def BMI(h, w):
return w/((h/100)**2)
height, weight = map(float, input('請輸入您的身高及體重:').split())
print(BMI(height, weight))
6. 函式的相互呼叫
def add(a, b):
return a+b
def avg(a, b):
return add(a, b)/2
while 1:
m, n = map(int, input("請輸入兩個整數:").split())
print(avg(m,n))
可以同時存在多個函式
7. 【補充】閉包(closure)函式
原先沒有closure,我們需要傳遞a, b, x參數,closure可以讓程式設計更有效率,同時未來擴充時,程式碼可以更容易移植
def outer(a, b):
'''a和b是inner()的環境變數'''
def inner(x):
return a*x+b
return inner
f1=outer(1, 2)
f2=outer(3, 4)
print(f1(1)) # 3
print(f2(3)) # 13
II. 遞迴
其實就是自己呼叫自己的函式
A. 遞迴的必要條件
B. 範例
【範例一】請用遞迴方式計算n層香檳塔共有幾個杯子
觀察:
1層香檳塔 → 1個杯子
2層香檳塔 → 5個杯子
......
n層香檳塔 → ?
歸納:
是否存在遞迴關係式?A:Sn=Sn−1+n×n
是否有最終停止的點?A:S1=1
程式碼:
# 遞迴寫法(1)
def sum_champagne_glass(n):
if n == 1:
return 1
else:
return sum_champagne_glass(n-1) + n*n
# 遞迴寫法(2)
def sum_champagne_glass(n):
if n == 1:
return 1
return sum_champagne_glass(n-1) + n*n
# 迴圈寫法
def sum_champagne_glass(n):
sum = 0
for i in range(1, n+1):
sum += i*i
return sum
while 1:
i = int(input("請輸入層數:"))
print('總共有:',sum_champagne_glass(i),'個酒杯')
遞迴並不是在任何情況下都比迴圈來的好用
遞迴就只是自己呼叫自己的函式
【範例二】請用遞迴方式計算出n階乘的值
觀察:
0! → 1
1! → 1
2! → 2
.....
n! → ?
歸納:
是否存在遞迴關係式?A:Fn=Fn−1×n
是否有最終停止的點?A:F0=1
程式碼:
# 遞迴寫法
def factorial(n):
if n==0:
return 1
return factorial(n-1)*n
while 1:
i = int(input('請輸入您想計算的階乘:'))
print(factorial(i))
# 迴圈寫法
def factorial(n):
accumulate = 1
if n==0:
return 1
for i in range(2, n+1):
accumulate *= i
return accumulate
while 1:
i = int(input('請輸入您想計算的階乘:'))
print(factorial(i))