核心知識點:
(1)一般的if/else是前面不執行,后面才執行,循環下面的else是前面執行完后面才會執行,如果是break打斷也不會執行。循環為空或False也不執行。
(2)try/expect是前面不執行后面才會執行,try/expect/else是try執行成功才會執行else,也就是expect不執行;try/finally不管前面是否執行后面都會執行。
(3)不要在循環后面使用else,這會讓人很費解。
Python提供了一種很多編程語言都不支持的功能,那就是可以在循環內部的語句后面直接編寫else。
>>> for i in range(3): ... print('Loop %d' % i) ... else: ... print('Else block!') ... Loop 0 Loop 1 Loop 2 Else block!
奇怪的是,這種else塊會在整個循環執行完之后立刻執行。既然如此,那為什么叫做else呢?為什么不叫and?
在if/else語句中,else的意思是:如果不執行前面那個if塊,那就執行else塊。
在try/expect語句中,expect的定義也類似:如果前面那個try塊沒有成功執行,那就執行expect塊。
同理,try/expect/else也是如此,該結構的else含義是:如果前面的try塊沒有失敗,那就執行else。
try/finally的意思是:執行過前面的try塊之后,總是執行finally塊。
明白了else、expect和finally的含義之后,剛接觸Python的程序員可能會把for/else結構中的else理解為:
如果循環沒有正常執行完,那就執行else塊。實際上剛好相反——在循環里用break語句提前跳出,會導致程序不執行else塊。
>>> for i in range(3): ... print('Loop %d' % i) ... if i == 1: ... break ... else: ... print('Else block!') ... Loop 0 Loop 1 #沒有執行else
還有一個奇怪的地方:如果for循環要遍歷的序列是空的,那么就會立刻執行else塊。
>>> for x in []: ... print('Never runs') ... else: ... print('For Else block!') ... For Else block!
初始循環條件為false的while循環,如果后面跟着else,那它也會立刻執行。
>>> while False: ... print('Never runs') ... else: ... print('While Else block!') ... While Else block!
知道了循環后面的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
上面的式子可以判斷兩個數是否有除了1之外的公約數,如果有,則不會打印Compire,如果沒有,就會打印Compire。
實際上,我們不會這樣寫代碼,而是會用輔助函數來完成計算,這樣的輔助函數有兩種常見的寫法。
第一種寫法是,只要發現受測參數符合自己想要搜尋的條件,就盡早返回。如果整個循環都完整地執行了一遍,那就說明受測參數不符合要求,於是返回默認值。
>>> def coprime(a,b): ... for i in range(2,min(a,b) + 1): ... if a % i == 0 and b % i == 0: ... return False ... return True
第二種寫法是,用變量來記錄首測參數是否符合自己想要搜尋的條件。一旦符合,就用break跳出循環。
>>> def coprime2(a,b): ... is_coprime == True ... for i in range(2,min(a,b) + 1): ... if a % i == 0 and b % i == 0: ... is_coprime == False ... breake ... return is_coprime #這種方法只是上面那一種方法的升級版
對於不熟悉for/else的人來說,這兩種寫法都要比早前那種寫法清晰很多。
for/else結構中的else塊雖然也能夠實現相應的功能,但是會令閱讀代碼的人相當不解,因為它不是屬於常規邏輯。
像循環這種簡單的語言結構,在python程序中應該寫得非常直白才對,我們完全不應該在循環的后面使用else塊
文章摘抄於Brett Slatkin的《編寫高質量Python代碼的59個有效方法》,僅作為個人學習使用,如有侵權請告知,將及時刪除,如果覺得有益,請購買原版書籍,知識需要傳遞和支持,謝謝。