8 集合、字典
尋找詩句交集字 (二)
36
withopen("poems.dat”) as infile :
for n , line in enumerate(infile) :
# 去除標點符號
poem = set( filter( lambda c : c not in " 。 , " , line.strip() ) )
if n == 0 :
words = poem.copy()
else :
words.intersection_update(poem)
print( " ".join( words ) )
輸出:
春 風
3.
8 集合、字典
尋找詩句交集字 (三)
37
withopen("poems.dat") as infile :
for n , line in enumerate(infile) :
line = line.strip()
if line == "" : continue
ws = sorted( [ c for c in line if c not in "。," ] )
if n == 0 :
# 交集字串列
cwords = []
for w in ws :
if w not in cwords : cwords += [w] # 避免儲存重複字
else :
# 新的交集字串列
new_cwords = []
for w in ws :
if w in cwords : new_cwords += [w] # 找新交集字
# 更新交集字
cwords = new_cwords[:]
# 列印交集字
print( " ".join(cwords) )
以下為完全使用串列的程式版本,觀察程式碼可知在讀進第二首詩後,每次都需使
用迴圈設定新的交集串列,與前相較,就顯得麻煩許多。
8 集合、字典
列印課表 (三)
40
num= ’一二三四五’
n = ’四’
# 回傳 n 在 num 字串的下標,n 若不在 num 內回傳 -1
k = num.find(n)
# 回傳 n 在 num 字串的下標,n 若不在 num 內則產生錯誤訊息
k = num.index(n)
本範例是個很簡單的字典應用問題,本程式可不透過字典取得下標,
直接使用字串搜尋 find() 或尋找下標 index() 取得下標,使用如下:
7.
8 集合、字典
列印課表 (四)
41
Day, Section = 5 , 8
cnum = ’一二三四五’
# 中文數字對數字字串下標
c2n = { b : a for a , b in enumerate(cnum) }
# 兩維串列:儲存五天八節的課程名稱
wkclass = [ [None]*Day for i in range(Section) ]
with open(”schedule.dat”) as infile :
for line in infile :
course , *csect = line.split()
# p 為 星期幾:節數,例如:四:567
for p in csect :
a , b = p.split(’:’)
# w 為 wkclass 的第二個下標
w = c2n[a]
for c in b :
# s 為 wkclass 的第一個下標
s = int(c)-1
wkclass[s][w] = course[0]
8.
8 集合、字典
列印課表 (五)
42
#印出課程表
print( ” | ” + ” ”.join( cnum ) )
print( ”-”*(5+3*5) )
for s in range(Section) :
if s == 4 : print( ”-”*(5+3*5) )
print( ” ”+str(s+1)+” | ” , end=”” )
for w in range(Day) :
print( wkclass[s][w] if wkclass[s][w] else ” ” , end=” ” )
print()
8 集合、字典
各洲國家在教育支出佔 gdp百分率的前五名 (三)
45
然後透過整數下標分別取得資料,這種儲存方式在取用資料很是麻煩,
例如:以下要找出亞洲所有國家的 gdp 教育支出百分率:
各洲與洲內的國家本是相關的資料組合,使用兩個串列分開儲存造成洲與洲
內的國家需找尋同位置的整數下標來連結,這樣的處置是很笨拙的。相形之下使
用字典是相當直接了當,以上程式若改用字典一列就解決,兩相對比,使用字典
的好處就不言而喻。
本題使用 subplots 將五張圖形印在一起,有關 subplots 的用法也可
參考累積雨量範例,只要參照相關用法即能很快學會如何產生矩陣列排列圖形。
foo = "Asia"
for i in range( len(continents) ) :
if continents[i] == foo : # 找到下標
gdps = nationgdps[i]
break
print( gdps )
print( ctn[”Asia”] ) # ctn 為程式範例的字典
12.
8 集合、字典
各洲國家在教育支出佔 gdp百分率的前五名 (四)
46
import pylab
# 索引:洲名,對映值:( 國名 + 資料年份 , gdp ) 串列
ctn = {}
with open("edu2.dat") as infile :
for line in infile :
# 分離資料再重新組合 ( 國名+年 , gdp ) 常串列
*nation , gdp , year , continent = line.split()
if gdp == ’n.a.’ : gdp = "-1"
data = ( " ".join(nation) + " [" + year + "]" , float(gdp) )
# 跨兩洲的國家以斜線分割:如俄羅斯
for c in continent.split(’/’) :
if c in ctn :
ctn[c].append( data )
else :
ctn[c] = [ data ]
no = 5
xs = [ x for x in range(0,17,2) ]
ys = [ y for y in range(no,0,-1) ]
13.
8 集合、字典
各洲國家在教育支出佔 gdp百分率的前五名 (五)
47
colors = ’rgbcmyk’
nrows , ncols = 3 , 2
# 區分 3x2 圖形五圖,共用 x , y 軸
fig , gs = pylab.subplots(nrows,ncols,facecolor=’w’)
# hspace 設定縱向兩圖間的間距(平均縱軸高度的比例)
# wspace 設定橫向兩圖間的間距(平均橫軸寬度的比例)
pylab.subplots_adjust(hspace=0.8,wspace=0.5)
# 依洲名排序
for i , k in enumerate( sorted( ctn.keys() ) ) :
r = i//ncols
c = i%ncols
# 各洲國家排列:先比 gdp 再比國名
ctn[k].sort( key = lambda p : ( -p[1] , p[0] ) )
# 儲存前 no 筆資料 vals:gdp% , nations:國名
vals , nations = [] , []
for j , p in enumerate(ctn[k]) :
vals.append(p[1])
nations.append(p[0])
if j+1 == no : break
14.
8 集合、字典
各洲國家在教育支出佔 gdp百分率的前五名 (六)
48
# 設定第一名國家顏色與其餘四國顏色不同
gs[r][c].barh( ys[0],vals[0],align=’center’,color=colors[i] )
gs[r][c].barh( ys[1:],vals[1:],align=’center’,color=’#aaffaa’ )
# 設定子圖文字說明
gs[r][c].set_title( "Top " + str(no) +
" nations spend more gdp%n on education in "
+ k , color=colors[i] )
# X 軸文字
gs[r][c].set_xlabel("gdp percentage")
# X 軸刻度
gs[r][c].set_xticks(xs)
# Y 軸刻度
gs[r][c].set_yticks(ys)
# Y 軸刻度文字
gs[r][c].set_yticklabels(nations,color=’k’)
# 顯示垂直格線
gs[r][c].grid(axis=’x’)
# 去除最後一個圖形軸線
gs[2][1].axis(’off’)
pylab.show()