浙教版《選擇性必修一數(shù)據(jù)和數(shù)據(jù)結(jié)構(gòu)》第一章是全書的導(dǎo)論,起到了提綱挈領(lǐng)的作用。其中“1.2.3 數(shù)據(jù)結(jié)構(gòu)的作用”,通過兩個案例來說明對同一問題的解決,可以依據(jù)不同數(shù)據(jù)結(jié)構(gòu)來設(shè)計(jì)算法,其效率是不一樣的。兩個案例較為典型,且有一定難度,教師應(yīng)根據(jù)學(xué)生實(shí)際,采用算法分析、代碼講解或過程演示等不同方法授課。表1.2.1只顯示了部分學(xué)生的信息,雖然對于分析算法來說已經(jīng)足夠了,但落實(shí)到具體的編程則稍顯不夠。為了便于編程,筆者把學(xué)生人數(shù)增加到6個,并修改班級編號為1-3,如下圖所示。
閱讀教材中“趣味運(yùn)動會項(xiàng)目”材料,思考如何存儲和組織如上表格中的數(shù)據(jù),并統(tǒng)計(jì)每位選手的總分和各班級的總分。(1)回顧數(shù)據(jù)元素和數(shù)據(jù)類型的概念,分析如上表格中有幾個數(shù)據(jù)元素?每個數(shù)據(jù)元素包含幾個數(shù)據(jù)項(xiàng)?各數(shù)據(jù)項(xiàng)的名稱是什么?屬于何種數(shù)據(jù)類型?(2)能否使用一維數(shù)組來存儲某條記錄,分別把該條記錄的各數(shù)據(jù)項(xiàng)依次作為數(shù)組元素?例如stu1= ['陳濤', 1,3,0,2,0,0,0,0],能把stu1稱之為數(shù)組嗎?為什么?(3)若使用一維數(shù)組來組織數(shù)據(jù),想要把如上表格中的數(shù)據(jù)都存儲起來,需要幾個一維數(shù)組?每個數(shù)組分別存儲哪些數(shù)據(jù)?其元素屬于何種數(shù)據(jù)類型?編程輸出如下內(nèi)容:(4)要在第(3)問基礎(chǔ)上編程統(tǒng)計(jì)每位選手的總分和各班級的總分,還需要創(chuàng)建幾個一維數(shù)組?其數(shù)據(jù)類型分別是什么?編程計(jì)算總分,并輸出如下內(nèi)容:(5)二維數(shù)組有行優(yōu)先和列優(yōu)先存儲兩種方式,請分別用這兩種方式組織數(shù)據(jù),實(shí)現(xiàn)程序功能,并分析與一維數(shù)組相比,它有何優(yōu)缺點(diǎn)?(6)如下程序能夠存儲上述數(shù)據(jù),并統(tǒng)計(jì)每位選手的總分和各班級的總分(輸出效果如下圖所示)。請仔細(xì)閱讀代碼,回答注釋中的提問,并將代碼補(bǔ)充完整。xm = ['陳濤', '楊瓊', '金凱','吳敏', '朱剛強(qiáng)', '李海濤']a = [[1,3,0,2,0,0,0,0],[3,0,0,0,0,5,1,0],[2,0,4,5,0,0,0,0], # a[0][1]、a[1][0]和a[2]的值分別是多少? [1,6,1,0,3,0,0,0],[2,5,0,1,0,7,0,0],[3,0,3,0,5,0,6,0]] # 這樣存儲數(shù)據(jù)有什么缺陷?# 輸出比賽得分信息print('姓名','班級','滾鐵圈','打彈子','拍紙板','竹蜻蜓','跳繩','踢毽子',sep="\t")for i in range(0,len(xm)): pass # 請編寫代碼,輸出如上圖所示的比賽得分信息# 計(jì)算個人總分和班級團(tuán)體總分bjdf = [0] * 4 # 3個班為什么要分配4個元素空間?for i in range(0,len(xm)): for j in range(1, 7): a[i][7] = 填空1 # a[i][7]的值是什么? bjdf[a[i][0]] = 填空2 # a[i][0]的值是什么?bjdf[a[i][0]]的值是什么? print(a[i][7], end=", ")print() # 本條語句的功能是什么?若刪除它有何后果?print(bjdf)
(7)除了使用一維數(shù)組和二維數(shù)組組織上述數(shù)據(jù),你還能想到其他方法嗎?例如使用字典或DataFrame數(shù)據(jù)結(jié)構(gòu)。(1)如上表格中每一行實(shí)際內(nèi)容就是一條記錄(數(shù)據(jù)元素);每個數(shù)據(jù)元素包含8個數(shù)據(jù)項(xiàng),各數(shù)據(jù)項(xiàng)的名稱依次為“姓名”、“班級”、“滾鐵圈”、…、“踢毽子”;除了“姓名”是字符串類型以外,其他數(shù)據(jù)項(xiàng)都可以用整型數(shù)據(jù)來表示。說明:一般情況下,“班級”用字符串來表示,在本例中,為編程方便,也可以用整型數(shù)據(jù)來表示。(2)若stu1= ['陳濤', 1,3,0,2,0,0,0,0],則不能把stu1稱之為數(shù)組。因?yàn)閿?shù)組是一種數(shù)據(jù)結(jié)構(gòu),要求其所有元素的數(shù)據(jù)類型均相同。說明:Python語言使用列表來模擬數(shù)組,但列表本身不是數(shù)組,它比數(shù)組更靈活。(3)因?yàn)槊織l記錄都包含8個數(shù)據(jù)項(xiàng),所以需要8個數(shù)組分別存儲每一列,每列表示一類數(shù)據(jù)項(xiàng)。編寫程序如下:xm = ['陳濤', '楊瓊', '金凱', '吳敏', '朱剛強(qiáng)', '李海濤']bj = [1, 3, 2, 1, 2, 3]d1 = [3, 0, 0, 6, 5, 0]d2 = [0, 0, 4, 1, 0, 3]d3 = [2, 0, 5, 0, 1, 0]d4 = [0, 0, 0, 3, 0, 5]d5 = [0, 5, 0, 0, 7, 0]d6 = [0, 1, 0, 0, 0, 6]print('姓名','班級','滾鐵圈','打彈子','拍紙板','竹蜻蜓','跳繩','踢毽子',sep="\t")for i in range(0, len(xm)): print(xm[i],bj[i],d1[i],d2[i],d3[i],d4[i],d5[i],d6[i],sep="\t")
(4)可以創(chuàng)建一維數(shù)組tot用來存儲所有學(xué)生的總分,其中tot[i]表示編號為i的學(xué)生的總分;可以創(chuàng)建一維數(shù)組bjdf用來存儲所有學(xué)生的總分,其中bjdf[i]表示第i班的總分。它們的數(shù)據(jù)類型均為整型。編程計(jì)算總分,代碼如下:tot = [0] * 6bjdf = [0] * 4 for i in range(0, len(xm)): tot[i] = d1[i]+d2[i]+d3[i]+d4[i]+d5[i]+d6[i] bjdf[bj[i]] += tot[i] print('各選手總得分:')print('姓名','總分',sep="\t")for i in range(0, len(xm)): print(xm[i],tot[i],sep="\t")print('各班級總得分:')print('班級','總分',sep="\t")for i in range(1, max(bj)+1): print(i,bjdf[i],sep="\t")
(5)使用二維數(shù)組按行優(yōu)先存儲數(shù)據(jù)時,因?yàn)榘嗉壝Q也是用整數(shù)表示,可以把它和各項(xiàng)目得分一起存儲到數(shù)組中;但姓名是字符串,必須單獨(dú)處理。參考代碼如下:xm = ['陳濤', '楊瓊', '金凱','吳敏', '朱剛強(qiáng)', '李海濤']a =[[1,3,0,2,0,0,0,0],[3,0,0,0,0,5,1,0],[2,0,4,5,0,0,0,0], [1,6,1,0,3,0,0,0],[2,5,0,1,0,7,0,0],[3,0,3,0,5,0,6,0]] # 按行優(yōu)先存儲
上述代碼中a[i]表示編號為i的學(xué)生的班級和各項(xiàng)目得分?jǐn)?shù)據(jù),符合人類的視覺感受,但畢竟班級名稱不是數(shù)值,不能參與算術(shù)運(yùn)算,與項(xiàng)目得分還是有本質(zhì)區(qū)別,故把它們放在一起不夠妥當(dāng)??梢詫ΧS數(shù)組按列優(yōu)先存儲數(shù)據(jù),即把每一列的內(nèi)容放在一維數(shù)組中。參考代碼如下:xm = ['陳濤', '楊瓊', '金凱','吳敏', '朱剛強(qiáng)', '李海濤']a = [[1, 3, 2, 1, 2, 3],[3, 0, 0, 6, 5,0],[0, 0, 4, 1, 0, 3],[2, 0, 5, 0, 1, 0], [0, 0, 0, 3, 0, 5],[0, 5, 0, 0, 7, 0],[0, 1, 0, 0, 0, 6],[0] * len(xm)] # 按列優(yōu)先存儲
(6)如題程序是使用按行優(yōu)先存儲數(shù)據(jù)的,a[0][1]和a[1][0]的值均為3,但含義不一樣,a[0][1]=3表示陳濤同學(xué)的滾鐵圈成績?yōu)?分,a[1][0]=3表示楊瓊同學(xué)的班級號為3,a[2]的值為[2,0,4,5,0,0,0,0],存儲了金凱同學(xué)的班級號和各項(xiàng)目得分。語句bjdf = [0]
* 4為數(shù)組bjdf分配了4個元素空間,原因是bjdf以班級號為下標(biāo),最大班級號為3。為避免下標(biāo)越界,需要為數(shù)組分配4個元素空間,這樣雖然浪費(fèi)了bjdf[0]的空間,但是可以直接使用bjdf[i]表示班級i的總分,給編程帶來了方便。a[i][7]表示第i個同學(xué)的總得分,例如a[0][7]表示陳濤同學(xué)的總得分;a[i][0]表示第i個同學(xué)所在班級的編號,例如a[0][0]表示陳濤同學(xué)的班級號;bjdf[a[i][0]]表示班級a[i][0]的總分,例如bjdf[a[0][0]],即bjdf[1],表示1班的總分。xm = ['陳濤', '楊瓊', '金凱','吳敏', '朱剛強(qiáng)', '李海濤']a =[[1,3,0,2,0,0,0,0],[3,0,0,0,0,5,1,0],[2,0,4,5,0,0,0,0], [1,6,1,0,3,0,0,0],[2,5,0,1,0,7,0,0],[3,0,3,0,5,0,6,0]] print('姓名','班級','滾鐵圈','打彈子','拍紙板','竹蜻蜓','跳繩','踢毽子',sep="\t")for i in range(0,len(xm)): print(xm[i],end="\t") for j in range(0, 7): print(a[i][j],end="\t") print()bjdf = [0] * 4 for i in range(0,len(xm)): for j in range(1, 7): a[i][7] += a[i][j] bjdf[a[i][0]] += a[i][7] print(a[i][7], end=", ")print()print(bjdf)
(7)可以使用字典來存儲多個一維數(shù)組,也可以把字典轉(zhuǎn)換成DataFrame對象,或者直接讀取Excel文件存儲到DataFrame對象中,從而調(diào)用pandas模塊的方法來編程,快速實(shí)現(xiàn)程序功能。代碼詳見“Python算法之旅”知識星球。使用多個一維數(shù)組存儲數(shù)據(jù),需要分別操作各個數(shù)組,實(shí)現(xiàn)協(xié)同工作的效果,對程序員要求較高,編程較為繁瑣,容易出錯。二維數(shù)組使用一個變量a,結(jié)合行、列下標(biāo)來組織管理數(shù)據(jù),能實(shí)現(xiàn)多個一維數(shù)組協(xié)同工作的效果,集中管理,組織效率更高,編程也更方便。使用字典來統(tǒng)一管理多個一維數(shù)組,也可以提高組織效率,增強(qiáng)代碼的可讀性。將字典轉(zhuǎn)換成DataFrame對象,或直接從Excel文件中讀取數(shù)據(jù)到DataFrame對象,可以利用現(xiàn)成的模塊方法,大大提高編程效率。
需要本文word文檔、源代碼和課后思考答案的,可以加入“Python算法之旅”知識星球參與討論和下載文件,“Python算法之旅”知識星球匯集了數(shù)量眾多的同好,更多有趣的話題在這里討論,更多有用的資料在這里分享。
我們專注Python算法,感興趣就一起來!
相關(guān)優(yōu)秀文章:
閱讀代碼和寫更好的代碼
最有效的學(xué)習(xí)方式
Python算法之旅文章分類