Python高能小技巧:不要在for与while循环后面写else块
導(dǎo)讀:本文會(huì)詳細(xì)介紹一個(gè)小技巧,幫助你用符合Python風(fēng)格的方式(Pythonic方式)來編寫程序。
作者:布雷特·斯拉特金(Brett Slatkin)
來源:大數(shù)據(jù)DT(ID:hzdashuju)
Python的循環(huán)有一項(xiàng)大多數(shù)編程語(yǔ)言都不支持的特性,即可以把else塊緊跟在整個(gè)循環(huán)結(jié)構(gòu)的后面。
for?i?in?range(3):print('Loop',?i) else:print('Else?block!') >>> Loop?0 Loop?1 Loop?2 Else?block!奇怪的是,程序做完整個(gè)for循環(huán)之后,竟然會(huì)執(zhí)行else塊里的內(nèi)容。既然是這樣,那為什么要叫“else”呢?這應(yīng)該叫“and”才對(duì)。在if/else結(jié)構(gòu)里,else的意思是:如果沒執(zhí)行前面那塊語(yǔ)句,那就執(zhí)行else塊。在try/except結(jié)構(gòu)里,except也是這個(gè)意思:如果前面那塊語(yǔ)句執(zhí)行失敗,那就執(zhí)行except塊。
try/except/else結(jié)構(gòu)里的else依然遵循這樣的理念,它的意思是:如果沒有異常需要處理,那就執(zhí)行這塊語(yǔ)句。try/finally結(jié)構(gòu)里的finally同樣很直觀,意思是:不管前面那塊代碼執(zhí)行得如何,最后都要執(zhí)行finally塊代碼。
了解了else、except、finally等在上面那些結(jié)構(gòu)里的用法,Python新手可能就覺得,for/else結(jié)構(gòu)里的else也是這個(gè)意思,即如果循環(huán)沒有從頭到尾執(zhí)行完,那就執(zhí)行else塊。實(shí)際上恰恰相反,如果循環(huán)沒有從頭到尾執(zhí)行完(也就是循環(huán)提前終止了),那么else塊里的代碼是不會(huì)執(zhí)行的。在循環(huán)中使用break語(yǔ)句實(shí)際上會(huì)跳過else塊。
for?i?in?range(3):print('Loop',?i)if?i==1:break else:print('Else?b1ock!') >>> Loop?0 Loop?1還有一個(gè)奇怪的地方是,如果對(duì)空白序列做for循環(huán),那么程序立刻就會(huì)執(zhí)行else塊。
for?x?in?[]:print('Never?runs') else:print('For?Else?block!') >>> For?Else?block!while循環(huán)也是這樣,如果首次循環(huán)就遇到False,那么程序也會(huì)立刻運(yùn)行else塊。
while?False:print('Never?runs') else:print('While?Else?block!') >>> While?Else?block!把else設(shè)計(jì)成這樣,是想讓你利用它實(shí)現(xiàn)搜索邏輯。
例如,如果要判斷兩個(gè)數(shù)是否互質(zhì)(也就是除了1之外,是不是沒有別的數(shù)能夠同時(shí)整除它們),就可以用這種結(jié)構(gòu)實(shí)現(xiàn)。先把有可能同時(shí)整除它們的數(shù)逐個(gè)試一遍,如果全都試過之后還是沒找到這樣的數(shù),那么循環(huán)就會(huì)從頭到尾執(zhí)行完(這意味著循環(huán)沒有因?yàn)閎reak而提前跳出),然后程序就會(huì)執(zhí)行else塊里的代碼。
a?=?4 b?=?9 for?i?in?range(2,?min(a,?b)?+?1):print('Testing',i)if?a?%?i?==?0?and?b?%?i?==?0:print('Not?coprime')break else:print('Coprime') >>> Testing?2 Testing?3 Testing?4 Coprime實(shí)際工作中,筆者不會(huì)這樣寫,而是會(huì)改用輔助函數(shù)完成計(jì)算。這樣的輔助函數(shù)有兩種常見的寫法。
第一種寫法是,只要發(fā)現(xiàn)某個(gè)條件成立,就立刻返回,如果始終都沒碰到這種情況,那么循環(huán)就會(huì)完整地執(zhí)行,讓程序返回函數(shù)末尾的那個(gè)值作為默認(rèn)返回值。
def?coprime(a,?b):for?i?in?range(2,?min(a,?b)?+?1):if?a?%?i?==?0?and?b?%?i?==?0:return?Falsereturn?Trueassert?coprime(4,?9) assert?not?coprime(3,?6)第二種寫法是,用變量來記錄循環(huán)過程中有沒有碰到這樣的情況,如果有,那就用break提前跳出循環(huán),如果沒有,循環(huán)就會(huì)完整地執(zhí)行,無論如何,最后都返回這個(gè)變量的值。
def?coprime_alternate(a,?b):is_coprime?=?Truefor?i?in?range(2,?min(a,?b)?+?1):if?a?%?i?==?0?and?b?%?i?==?0:is_coprime?=?Falsebreakreturn?is_coprime assert?coprime_alternate(4,?9) assert?not?coprime_alternate(3,?6)對(duì)于不熟悉for/else結(jié)構(gòu)的人來說,剛才那兩種寫法都是比較清晰的方案,大家可以根據(jù)情況選擇其中的一種。
for/else或while/else結(jié)構(gòu)本身雖然可以實(shí)現(xiàn)某些邏輯表達(dá),但它給讀者(也包括你自己)帶來的困惑,已經(jīng)蓋過了它的好處。因?yàn)閒or與while循環(huán)這種簡(jiǎn)單的結(jié)構(gòu),在Python里面讀起來應(yīng)該相當(dāng)明了才對(duì),如果把else塊緊跟在它的后面,那就會(huì)讓代碼產(chǎn)生歧義。所以,請(qǐng)不要這么寫。
要點(diǎn)
Python有種特殊的語(yǔ)法,可以把else塊緊跟在整個(gè)for循環(huán)或while循環(huán)的后面。
只有在整個(gè)循環(huán)沒有因?yàn)閎reak提前跳出的情況下,else塊才會(huì)執(zhí)行。
把else塊緊跟在整個(gè)循環(huán)后面,會(huì)讓人不太容易看出這段代碼的意思,所以要避免這樣寫。
關(guān)于作者:布雷特·斯拉特金(Brett Slatkin),Google首席軟件工程師,他是Google Surveys的聯(lián)合技術(shù)創(chuàng)始人,也是PubSubHubbub協(xié)議的共同創(chuàng)造者之一。此外,Slatkin還發(fā)布了Google的第一個(gè)云計(jì)算產(chǎn)品——App Engine。早在15年前,Slatkin就開始在工作中使用Python管理Google大量的服務(wù)器群。他擁有紐約哥倫比亞大學(xué)計(jì)算機(jī)工程專業(yè)學(xué)士學(xué)位。
本文摘編自《Effective Python:編寫高質(zhì)量Python代碼的90個(gè)有效方法》(原書第2版),經(jīng)出版方授權(quán)發(fā)布。
延伸閱讀《Effective Python》(原書第2版)
點(diǎn)擊上圖了解及購(gòu)買
轉(zhuǎn)載請(qǐng)聯(lián)系微信:DoctorData
推薦語(yǔ):Python編程進(jìn)階必讀,基于Python3.8,新增31條建議!掌握Pythonic編程方式,寫出高質(zhì)量代碼|進(jìn)階到編程高手的程序員修煉之道和代碼整潔之道。
劃重點(diǎn)????
干貨直達(dá)????
終于有人把量化投資講明白了
人工智能時(shí)代都需要哪些數(shù)學(xué)知識(shí)?這些經(jīng)典教材給你劃重點(diǎn)
4種數(shù)據(jù)分析基礎(chǔ)方法,終于有人講明白了
那兩個(gè)告扎克伯格抄襲的斜杠青年,后來怎么樣了?
更多精彩????
在公眾號(hào)對(duì)話框輸入以下關(guān)鍵詞
查看更多優(yōu)質(zhì)內(nèi)容!
PPT?|?讀書?|?書單?|?硬核?|?干貨?|?講明白?|?神操作
大數(shù)據(jù)?|?云計(jì)算?|?數(shù)據(jù)庫(kù)?|?Python?|?可視化
AI?|?人工智能?|?機(jī)器學(xué)習(xí)?|?深度學(xué)習(xí)?|?NLP
5G?|?中臺(tái)?|?用戶畫像?|?1024?|?數(shù)學(xué)?|?算法?|?數(shù)字孿生
據(jù)統(tǒng)計(jì),99%的大咖都關(guān)注了這個(gè)公眾號(hào)
????
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的Python高能小技巧:不要在for与while循环后面写else块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5个步骤带你入门FPGA设计流程
- 下一篇: Netflix正在搞的混沌工程到底是什么