iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 4
3
Software Development

活用python- 路遙知碼力,日久練成精系列 第 4

Day4- Python內建函數是你的好夥伴,認識max(), min(), len(),sorted(),sum(),abs(), pow()

路遙知碼力,日久練成精- 只要在程式之路鑽研的夠深,便能夠充分發揮程式碼的力量; 練習的日子夠久,便能夠練成寫出精簡代碼的能力。

我們正式進入寫出精簡代碼的第一課- 善用內建函數。
善用內建函數就像是站在巨人的肩榜上,
既然已經有現成的函式庫了,
何必自己再費時去實作那些功能呢?

譬如說寫排序演算法常常是學程式的人必學的課題,
而在python中已經有sorted函數,
便省去自己寫排序演算法的麻煩。

1. 找最大、最小值- max(), min()

max(), min()的參數用法相同,
max()裡面可以放多個參數,
或者是放入列表(list)、字串(str)、元組(tuple)、集合(set)、字典(dict),
該函數會回傳最大值,
如果放字串的話則會回傳字串裡字元的ascii碼最大值
(白話解說: 字母順序愈後面者愈大; 小寫字母大於大寫字母)。
例子:

>>> max(-10,20,0,-20)
20
>>> max(-10,-20,-30,-40)
-10
>>> max([1,2,3])
3
>>> max("Hello")
o
>>> min("Hello")
H
>>> max([(1,0),(1,1),(2,1),(2,0)])
(2,1)
>>> min([(1,0),(1,1),(2,1),(2,0)])
(1,0)

需要注意的是,若是元組比大小,
會先比較第一個元素,若第一個元素大的則比較大,
第一個元素都相同時才去比較第二個元素。
因此[(1,0),(1,1),(2,1),(2,0)]中的最大值為(2,1),最小值為(1,0)。

範例4-1 小明的考試- 多一分賞一元

善用min(), max()可以精簡很多程式碼,
看一個例子:
小明正在讀中學,
媽媽訂了一個獎勵制度:
只要小明該次考試超過70分,
每多1分就獎賞零用錢1元

以鼓勵小明讀書。

請你寫一個函數,
輸入為考試分數,
計算小明該次考試可以得到多少零用錢。

你可能會想說這不就是if-else判斷嗎?
很多人可能會很自然的這樣寫:

def prize(n):
    if n>70:
        return n-70
    else:
        return 0

函數參數n表示小明的考試分數,
邏輯是如果小明考試超過70分,回傳(n-70),
否則小明拿不到零用錢,回傳0。

但其實換個想法,代碼超簡單,
不論如何,小明拿到的零用錢不會是負數,
只需回傳(n-70)和0的最大值即可。

def prize(n):
    return max(n-70,0)

2. 取得字串、列表長度- len()

len()函數可以取得字串或是列表、元組、集合的長度或項目個數,
直接看例子:

>>> len([1,2,3,4,5])
5
>>> len("Hello World")
11 #空格也算一個字元

3. 實用排序函數- sorted()

sorted()函數可以對可迭代對象(如:列表、元組、集合)進行排序操作,
函數返回一個list,
預設會將元素由小排到大,
例如:

myList = [2,5,3,-6,10]
print(sorted(myList))

結果為 [-6, 2, 3, 5, 10]
如果希望元素由大排到小,
可以使用reverse=True 這個參數,
例如:

myList = [2,5,3,-6,10]
print(sorted(myList, reverse=True))

結果為[10, 5, 3, 2, -6]
sorted()亦可對字串排序:

print(sorted("Hello World"))

結果為 [' ', 'H', 'W', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r']

4. 求和- sum ()

可別以為這邊說的求和是「下象棋快輸了想與對方求和」的意思哦。
sum函數可以計算可迭代對象(如:列表、元組、集合)的數字總和,
例如:

>>> sum([1,2,3])
6
>>> sum([10.5,2.5,3.5])
16.5

範例4-2 計算全班考試分數平均

假設我們現在用一個列表來存班上每個人的數學考試分數,
例如:

scores = [50,60,35,20,40]

那麼如何計算班平均分數呢?
平均分數=全班分數總和/全班人數,
我們可以直接用內建函數來解:

scores = [50,60,35,20,40]
print("班平均分數為:", sum(scores)/len(scores))

5. 好用的數學函數- abs(), pow()

絕對值和計算次方是比較常見的數學操作,
abs(x)會回傳x的絕對值,
pow(x,y)會回傳x的y次方(y也可以是負數或小數),
例子:

>>> abs(-5)
5
>>> abs(66)
66
>>> pow(5,2)
25
>>> pow(9,0.5) #註: 0.5次方即是開根號的意思
3.0

另外,次方也可用python內建數學運算符 ** 來做,
例如 pow(5,2) 也可寫成是 5**2
比較特別的時,pow()函數也可以使用三個參數,
pow(x,y,z)會回傳x的y次方除以z的餘數,
其效果為pow(x,y)%z。

你可能會問啦,那幹麻不直接寫
pow(x,y)%z就好了,還要多記pow有三個參數的用法呢?

因為在算大數字的時候pow(x,y)%z會很慢
pow(x,y)%z會先把x的y次方計算出來,在把這個數對z取餘數,
可是其實要計算大數字次方的餘數時,
存在著不必先把x的y次方的數學技巧(也就是pow函數內部做的事),
這時就比較適合用pow(x,y,z)這個函數。
我們來驗證一下用不同方法計算大數字次方餘數的時間。

範例4-3 測量一段程式碼運行時間

呃,如果你沒寫過大型程式,
可能覺得程式都一瞬間就跑完了,
學這個有什麼用嗎?
但如果你的程式算法會影響到執行時間是一秒還是一百秒的時候,
差別可就大了。

要測量一段程式碼執行時間,
需要引入模組 time,
例如本程式計算一到一百萬的總和的時間:

import time

tStart = time.time() #計時開始
sum(range(1,1000001))
tEnd = time.time() #計時結束
print("Total time= %f seconds" % (tEnd - tStart))

time.time()函數可以取得從1970年起至現在此刻的秒數,
因此分別以tStarttEnd兩個變數各取得一次時間,
做為計時的開始與結束,
把想測量的程式碼放進tStart 和tEnd中間即可。
我的執行結果為Total time= 0.031243 seconds
注意本程式因每個人電腦效能不同,時間測出來不會相同。
即便同一台電腦執行同一支程式的時間也不會完全一樣。

範例4-4 計算大數字次方的尾數

假設我們現在想要計算1234的456789次方的個位數字是多少,
也就是計算1234的456789次方除以10的餘數。
我們用兩種不同的方法來計算:

import time

#方法一: 用內建函數計算
tStart = time.time()#計時開始
print(pow(1234,456789,10)) 
tEnd = time.time()#計時結束
print("方法一時間= %f seconds" % (tEnd - tStart))

#方法二: 先算出1234的456789次方再取餘數
tStart = time.time()#計時開始
print(pow(1234,456789)%10)
tEnd = time.time()#計時結束
print("方法二時間= %f seconds" % (tEnd - tStart))

我的執行結果為
4
方法一時間= 0.000000 seconds
4
方法二時間= 0.343645 seconds
哇,同樣算出了尾數為4,
但是方法一測出的時間為0秒,
幾手不花時間,
而方法二卻花了0.34秒,
內建函數果然好用。


上一篇
Day3 - 天啊我只有「螢幕十行」,python簡力救救我啊!
下一篇
Day5- 節約迴圈大作戰,方便的串接與重複運算: 「+」 與 「*」
系列文
活用python- 路遙知碼力,日久練成精30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
to790303
iT邦新手 5 級 ‧ 2019-09-19 19:53:46
scores = [50,60,35,20,40]
print("班平均分數為:", sum(scores)/len(scores)))

一馬老師您好,正在觀看此系列的文章,發現上述程式碼中,是否多了一個括號→)

另外想請教您,關於範例4-1的語法,我定義完函數後,該如何去把我的成績輸入呢?
新手學習中,請不吝嗇指教,謝謝/images/emoticon/emoticon02.gif

不明 檢舉
【**此則訊息已被站方移除**】
不明 檢舉
【**此則訊息已被站方移除**】
to790303 iT邦新手 5 級 ‧ 2019-09-19 22:40:16 檢舉

我會試著實作例題來練習,謝謝您的回覆/images/emoticon/emoticon33.gif

我要留言

立即登入留言