9 函式
修課時間排序 (三)
在程式中的排序規則函式,by_weekly_earlier_hr,首先分解各
列取出上課時間,在迴圈中將各個上課時間再度依冒號分解為中文數字與英
文數字字串,由此利用前述方法將各個上課鐘點轉為數字,回傳最小值。在
程式中,中文數字所對應的數字是先在主函式處理存成字典,名稱為 c2n
,再透過 global 方式給排序規則函式使用,這是不得已的作法,因為排
序規則函式僅接受由排序函式 sort 傳入的串列元素參數。在正常的情況
下程式設計要避免使用 global 變數,在下個範例會詳加說明使用
global 的缺點。
47
16.
9 函式
修課時間排序 (四)
48
defmain() :
global c2n
cnum = ’一二三四五’
c2n = dict( [ ( b , a ) for a , b in enumerate(cnum) ] )
with open("schedule.dat") as infile :
schedules = infile.readlines()
#依據課程在一周內最早上課時間排序
schedules.sort( key=by_weekly_earlier_time )
for s in schedules : print( s.rstrip() )
# 設定排序標準
def by_weekly_earlier_time( schedule ) :
global c2n
course , *csect = schedule.split()
all = []
for p in csect :
17.
9 函式
修課時間排序 (五)
49
#拆解上課時間
a , b = p.split(’:’)
w = c2n[a]
# 將此門課所有上課時間以整數表示
for c in b :
s = int(c)
all.append(w*10+s)
# 回傳該門課在一周最早上課時間所代表的整數
return sorted(all)[0]
# 執行主函式
main()
本題另有一種作法,即在讀入課程檔時,立即計算該門課的最早上課時間
對應數字,將課名與數字存入字典 snum,其資料為 {’化學’:3, ’國文
’:25 , ..., }。在排序時,只要用 split() 取得第一筆字串(即課名)
,馬上可使用 snum 得到該課最早上課時間的對應數字,以此數字當成排序
標準。這種程式寫法避免了之前程式需要不斷地執行排序規則函式,會讓程式
執行更有效率。
18.
9 函式
修課時間排序 (六)
50
defmain() :
global snum
cnum = ’一二三四五’
c2n = dict( [ ( b , a ) for a , b in enumerate(cnum) ] )
# 課程與上課時間
schedules = []
# 字典,儲存課名與一周最早上課時間比較數字
snum = {}
# 讀檔
with open("schedule.dat") as infile :
for line in infile :
schedule = line.strip()
schedules += [ schedule ]
# 回傳課程與其一周最早上課時間比較數字
course , num = course_eariler_number(schedule,c2n)
# 存入字典
snum[course] = num
19.
9 函式
修課時間排序 (七)
51
#依據課程在一周內最早上課時間排序
schedules.sort( key = lambda s : snum[s.split()[0]] )
# 列印
for s in schedules :
print( s.strip() )
# 尋找最早上課時間代表數字
def course_earlier_number( schedule , c2n ) :
# 分解課名與上課時間
course , *csect = schedule.split()
all = []
for p in csect :
# 拆解上課時間
a , b = p.split(’:’)
w = c2n[a]
# 將此門課所有上課時間以整數表示
for c in b :
s = int(c)
all.append(w*10+s)
return ( course , min(all) )
# 執行主函式
main()