Python中由生成杨辉三角代码所思考的一些问题
楊輝三角定義如下:
1/ \1 1/ \ / \1 2 1/ \ / \ / \1 3 3 1/ \ / \ / \ / \1 4 6 4 1/ \ / \ / \ / \ / \ 1 5 10 10 5 1把每一行看做一個(gè)list,試寫(xiě)一個(gè)generator,不斷輸出下一行的list。
該題目考查生成器的應(yīng)用。一般的思路是,首先在每一行輸出一個(gè)1,隨后通過(guò)循環(huán),位置i(從2開(kāi)始)的數(shù)是上一行i與i-1位置的數(shù)之和,當(dāng)i與上一行數(shù)字個(gè)數(shù)相同時(shí),循環(huán)終止,最后再添加進(jìn)一個(gè)1,形成新的一行。
基于這個(gè)基本思路,將python的生成器運(yùn)用到里面,有兩種常見(jiàn)的寫(xiě)法:
一種寫(xiě)法如下:
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! ''' def triangles():#楊輝三角的一種生成方法l = [1]while True : yield lfor i in range ( 1,len (l) ) :l [i] = h [i] + h [i-1] l.append (1)h = l[:]另外一種寫(xiě)法如下,運(yùn)用了list的生成式:
def triangles():l = [1] while True :yield ll = [1] + [ l[i] + l[i+1] for i in range ( len (l) - 1)] + [1]可以看到,以上兩種寫(xiě)法都是相當(dāng)簡(jiǎn)潔的。一開(kāi)始這兩個(gè)代碼看不太懂,比如說(shuō)為啥第一種寫(xiě)法里一開(kāi)始h里面沒(méi)有數(shù),卻也能夠正常執(zhí)行?主要是對(duì)于生成器的yield機(jī)制不明白,以及對(duì)于range的用法不是特別清楚。以下就這兩點(diǎn)分別解釋。
首先,當(dāng)函數(shù)中出現(xiàn)了yield之后,該函數(shù)就不再被視為函數(shù),而視為一個(gè)生成器。此時(shí),整個(gè)函數(shù)被使用的語(yǔ)句流程會(huì)發(fā)生改變,一般的函數(shù)都是調(diào)用的時(shí)候從函數(shù)入口進(jìn),發(fā)現(xiàn)return或函數(shù)執(zhí)行完畢后返回,而生成器函數(shù)則是每次調(diào)用函數(shù)執(zhí)行,執(zhí)行到y(tǒng)ield返回,下次再調(diào)用函數(shù)的時(shí)候從上次yield返回處繼續(xù)執(zhí)行。
其次,range的用法中是,如果是【range(x,x) 其中x是常量】的形式,range依然返回空。故在上述代碼的for循環(huán)中,由于在第一次試圖循環(huán)的時(shí)候,后面的range要么是range(1,1)要么是range(0),故都會(huì)成功避開(kāi)i或者h(yuǎn)沒(méi)有實(shí)際值的循環(huán),執(zhí)行接下來(lái)的部分。當(dāng)?shù)诙卧噲D循環(huán)開(kāi)始時(shí),i和h內(nèi)的內(nèi)容都已經(jīng)滿(mǎn)足條件了,所以就能正常運(yùn)行了。
還有一種我看到的最簡(jiǎn)單的寫(xiě)法:
''' 遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)! '''def triangles():L = [1]while True:yield LL= [(L + [0])[i] + ([0] + L)[i] for i in range(len(L)+1)]這一種寫(xiě)法直接去掉了第二種寫(xiě)法里每次L兩邊額外插入的[1],使其變?yōu)榱艘粋€(gè)完整的一個(gè)list生成式,可以說(shuō)是相當(dāng)精妙。
那么,這種寫(xiě)法為什么也可以呢?我們?cè)賮?lái)分析一下楊輝三角的性質(zhì),這樣,為了直觀理解,我們先利用上面的代碼,舉一個(gè)運(yùn)行中的過(guò)程例子。
比如,L此時(shí)為[1,1](楊輝三角第二行),現(xiàn)在需要求第三行。根據(jù)第五行的生成式,將按照以下步驟進(jìn)行計(jì)算:
L尾部加0,得到[1,1,0],我們稱(chēng)之為tempL1
L首部加0,得到[0,1,1],我們稱(chēng)之為tempL2
現(xiàn)在,根據(jù)之后的for循環(huán),L最終要被賦值成由tempL1與tempL2對(duì)應(yīng)的每個(gè)相同位置數(shù)字之和所組成的列表,經(jīng)過(guò)計(jì)算,這個(gè)新的L應(yīng)該為[1,2,1]。居然確實(shí)是楊輝三角的第三行!
相信聰明的觀眾已經(jīng)明白了,這個(gè)最簡(jiǎn)單的寫(xiě)法是利用了楊輝三角本身的對(duì)稱(chēng)性質(zhì),讓同一行錯(cuò)開(kāi)一位豎式相加,得到的就是下一行的結(jié)果。
同時(shí),利用python里面本身就極為方便的列表擴(kuò)展寫(xiě)法和列表生成式,才有了第三種如此簡(jiǎn)潔的寫(xiě)法~
總結(jié)
以上是生活随笔為你收集整理的Python中由生成杨辉三角代码所思考的一些问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python用HTMLTestRunne
- 下一篇: python中的del,remove,p