2. 星號式子 (一) : 用在串列變數
在等號左側 : 合併(打包)元素為串列
2python
在等號左側星號僅能有一個
函式參數設定 運算結果 說明
( a , *b ) = (1,2,3,4) a = 1 , b = [2,3,4] 小括號可省略
*a , b , c = [1,2,3,4] a = [1,2]
b = 3 , c = 4
*a , b = 1 錯誤 右式不是常串列,缺逗號
a , *b = 1 , a = 1 , b = []
*a , b = 1 , a = [] , b = 1
*a = 1 , 2 , 3 錯誤 左式不是常串列,缺逗號
*a , = 1 , 2 , 3 a = [1,2,3]
*a , = () a = []
3. 星號式子 (二)
3python
在等號右側 : 拆解串列成元素
函式參考設定 運算結果 說明
x = [4,5]
( a , b , c ) = ( 3 , *x )
a = 3
b = 4 , c = 5
小括號可省略
x = [1,2]
a , b = *x ,
a = 1
b = 2
末尾逗號不可省略
x = [1,2]
a , b , c = *x ,
錯誤 等號左側多一個變數
x = [1,2,3] , y = [4]
a , b , c , d = *x , *y
a = 1 , b = 2
c = 3 , d = 4
等號右側可有多個星
號用來拆解串列
7. enumerate 列舉函式 (二)
印出串列的次序與其值
若使用傳統方式,須另設整數:
7python
# 型式一:
for n , val in enumerate( [”rat”,”ox”,”tiger”,”rabbit”] ) :
print( n+1 , ’:’ , val )
# 型式二: p 為兩個元素的常串列
for p in enumerate( ["rat","ox","tiger","rabbit"] ) :
print( p[0]+1 , ’:’ , p[1] )
輸出:
1 : rat
2 : ox
3 : tiger
4 : rabbit
n = 0
for val in [”rat”,”ox”,”tiger”,”rabbit”] :
print( n+1 , ’:’ , val )
n += 1
8. zip 拉鏈函式 (一)
zip 拉鏈函式:在多個一維串列與一個多維串列之間互換
將多個一維串列合成一個多維串列
使用 list 將 zip 函式的輸出轉型為串列
8python
>>> a = list( zip( ["cat","dog","bird"] , [20,55,38] ) )
>>> a
[(’cat’, 20), (’dog’, 55), (’bird’, 38)]
9. 英文組句
由分量組成座標點
9python
zip 拉鏈函式 (二)
subjects = [ "John" , "Tom" , "Mary" ]
verbs = [ "likes" , "has" , "plays with" ]
objects = [ "cat" , "dog" , "parrot" ]
for s , v , o in zip( subjects , verbs , objects ) :
print( s , v , o )
輸出:
John likes cat
Tom has dog
Mary plays with parrot
>>> xs , ys , zs = [1,2,3] , [4,5,6] , [7,8,9]
>>> pts = list( zip( xs , ys , zs ) )
>>> pts
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
10. 將一個多維串列拆解為多個一維串列
拆解多維串列時需使用 * 星號於串列之前
分解動物與數量
10python
zip 拉鏈函式 (三)
>>> pets , num = zip( *[ (”birds”,35),(”dogs”, 20),(”cats”,15) ] )
>>> pets
(’birds’, ’dogs’, ’cats’)
>>> num
(35, 20, 15)
傳統方式撰寫:
pets , num = [] , []
for a , b in [ (”birds”,35),(”dogs”, 20),(”cats”,15) ] :
pets.append(a)
num.append(b)
17. 利用排序找出數字排列順序
17python
sort 與 sorted 排序函式 (五)
>>> a = [12,76,3,25]
>>> b = sorted(a)
# c 為 a 序列數字由小到大的順序編號
>>> c = [ b.index(x)+1 for x in a ]
>>> c
[2, 4, 1, 3]
# d 為 a 序列數字由大到小的順序編號
>>> b = sorted(a,reverse=True)
>>> d = [ b.index(x)+1 for x in a ]
>>> d
[3, 1, 4, 2]
18. map 映射函數 (一)
map(fn,foo) :逐一取出 foo 串列的元素送到 fn
函式處理
使用 list 將 map 函式的輸出轉型為串列
逐一印出字串前後字母,中間字元以星號取代
18python
>>> a = list( map( len , [ "cat", "tiger" , "lion" ] ) )
>>> a
[3, 5, 4]
>>> b = map( lambda x : x[0]+"*"*(len(x)-2)+x[-1] , [ "cat", "duck" ] )
>>> list(b)
[’c*t’, ’d**k’]
map 也可使用 list comprehension 得到同等效果
>>> a = [ len(x) for x in [ "cat", "tiger" , "lion" ] ]
20. map 映射函數 (三)
三角塔
印出字串與數字合併:a5 b7 c2
20python
for z in map( lambda x,y : x+str(y) , ["a","b","c"] , [5,7,2] ) :
print( z )
以上等同:
for z in [ x+str(y) for x , y in zip( ["a","b","c"] , [5,7,2] ) ] :
print( z )
>>> for x in map( lambda x : " "*(5-x)+"*"*(2*x+1),range(5))
: print(x)
*
***
*****
*******
*********
21. map 映射函數 (四)
21python
>>> sum( map( lambda x , y : x*y , [1,2,3] , [4,5,2] ) )
20
以上等同:
>>> sum( [ x*y for x , y in zip( [1,2,3] , [4,5,2] ) ] )
20
計算兩整數串列內積
22. filter 過濾函式
filter(fn,foo) :過濾出 foo 串列滿足 fn 函式條件的元素
使用 list 將 filter 函式的輸出轉型為串列
計算正數和
找出 [0,50] 間數字的個位數與十位數之和大於 10 的數
22python
>>> list( filter( lambda x : x > 0 , [1,3,-2,4,9] ) )
[1, 3, 4, 9]
>>> sum( filter( lambda x : x > 0 , [1,3,-2,4,9] ) )
17
>>> list( filter( lambda x : x//10+x%10 > 10 , range(51) ) )
[29, 38, 39, 47, 48, 49]
此種方式等同使用以下的 list comprehension
>>> [ x for x in [1,3,-2,4,9] if x > 0 ]
25. pylab 折線圖 (二)
操作範例:
25python
import pylab
a , b = -10*pylab.pi , 10*pylab.pi
n = 101
dx = (b-a)/(n-1)
# 分別計算 sin(x) 與 cos(x) 座標
xs = [ a + i * dx for i in range(n) ]
ys1 = [ pylab.sin(x) for x in xs ]
ys2 = [ pylab.cos(x) for x in xs ]
# 分別畫 sin(x) 與 cos(x) 折線圖
pylab.plot(xs,ys1)
pylab.plot(xs,ys2)
# 顯示圖形
pylab.show()
51. 畫出來的數字 (二)
51python
import pylab
bmap = ( (15,9,9,9,15), (2,2,2,2,2), (15,1,15,8,15), (15,1,15,1,15),
(9,9,15,1,1), (15,8,15,1,15), (15,8,15,9,15), (15,9,1,1,1),
(15,9,15,9,15), (15,9,15,1,15) )
# 每個矩矩陣的橫列數與直行數
R , C = len(bmap[0]) , 4
# 設定每個點矩陣位置的四方鄰居是否存在
nmap = []
for n in range(10) :
foo = [ [None]*C for i in range(R) ]
for r in range(R) :
for c in range(C) :
s = []
if bmap[n][r] & ( 1 << c ) :
if c > 0 :
# 檢查右側是否有點
if bmap[n][r] & ( 1 << (c-1) ) : s += [1]
if r > 0 :
# 檢查上方是否有點
if bmap[n][r-1] & ( 1 << c ) : s += [2]
if c < C-1 :
# 檢查左側是否有點
if bmap[n][r] & ( 1 << (c+1) ) : s += [3]
52. 畫出來的數字 (三)
52python
if r < R-1 :
# 檢查下方是否有點
if bmap[n][r+1] & ( 1 << c ) : s += [4]
foo[r][c] = sorted(s)
nmap += [ foo ]
# 設定每個數字的 ds 高, dt 寬
ds , dt = 1 , 0.8
while True :
# 輸入數字
num = input("> ")
pylab.figure(facecolor=’w’)
# 每列
for r in range(R) :
# 每個數字
for k in range(len(num)) :
# 每個位數
n = int(num[k])
# 每行
for c in range(C) :
53. 畫出來的數字 (四)
53python
# 中心點位置
x = ( k*C + k + (C-1-c) )*dt
y = (R-r)*ds
# 由每個點的中心位置畫到與鄰居點交界位置
for w in nmap[n][r][c] :
if w == 1 :
x2 , y2 = x+dt/2 , y
elif w == 2 :
x2 , y2 = x , y+ds/2
elif w == 3 :
x2 , y2 = x-dt/2 , y
elif w == 4 :
x2 , y2 = x , y-ds/2
pylab.plot( [x,x2] , [y,y2] , ’r’ , lw=20)
# 不要顯示兩個軸線
pylab.axis(’off’)
pylab.show()
54. 階梯函式 (一):使用 Fourier Series 逼近
54python
一些上下振盪的階梯函式經常需要使用 sin θ 或 cos θ 的線性
組合來逼近,其中最常使用的組合方式稱為傅立葉級數(Fourier
Series)。例如上方的階梯函數可透過下方的傅立葉級數來逼近。
本範例即是計算傅立葉級數與階梯函數的差距並以圖形顯示出來。
58. 58python
# 顯示上下兩圖,gs 為圖形串列:gs[0] 為上圖,gs[1] 為下圖
fig , gs = pylab.subplot(2,sharex=True)
# 上圖
gs[0].bar(xs,ys) # 畫直條圖
gs[0].grid() # 顯示格線
gs[0].set_title(”title”) # 設定圖形標頭
# 設定上圖的 Y 刻度文字 (因共用 X 軸, X 刻度文字由下圖控制)
# Y 軸在 [10,20,30] 等刻度分別顯示 A B C
pylab.setp( gs[0] , yticks=[10,20,30] , yticklabels=["A","B","C"] )
# 下圖
gs[1].plot(xs,ys1,label=”fn1”) # 畫折線圖並設定圖例文字
gs[1].plot(xs,ys2,label=”fn2”) # 畫折線圖並設定圖例文字
gs[1].set_xlabel(”X”) # 設定 x 軸文字
gs[1].set_ylabel(”Y”) # 設定 y 軸文字
gs[1].legend() # 顯示圖例
# 設定下圖的 X 與 Y 軸刻度文字,
# X 軸在 [0,1,2,3] 等刻度分別顯示 Cow Pig Chicken Fish
# Y 軸在 [10,20,30] 等刻度分別顯示 A B C
pylab.setp( gs[1] ,
xticks=[0,1,2,3] , xticklabels=["Cow","Pig","Chicken","Fish"] ,
yticks=[10,20,30] , yticklabels=["A","B","C"] )
pylab.show()
階梯函式 (五):
有關各函式更詳細的用法,請參考 matplotlib 網站
59. 59python
import pylab
from math import *
f , gs = pylab.subplots(2, sharex=True)
m = int( input("no of terms : ") )
a , b , np = 0 , 2 , 400
dx = (b-a)/np
xs = [ a + i * dx for i in range(np+1) ]
ys = [ None ] * (np+1)
ss = [ 1 if x<=1 else 0 for x in xs ]
# 計算 Fourier Series 的估算值
for i , x in enumerate(xs) :
y , pix = 0 , pi * x
for j in range(m) : y += sin((2*j+1)*pix)/(2*j+1)
ys[i] = 0.5 + 2*y/pi
階梯函式 (六):