摘要:可以通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)展示當(dāng)然,也可以用狀態(tài)變量的做法來(lái)替代總結(jié)有人覺得的這些用法違反直覺或者是而非,不值得提倡。
項(xiàng)目地址:https://git.io/pytips
我們都知道 Python 中 else 的基本用法是在條件控制語(yǔ)句中的 if...elif...else...,但是 else 還有兩個(gè)其它的用途,一是用于循環(huán)的結(jié)尾,另一個(gè)是用在錯(cuò)誤處理的 try 中。這原本是 Python 的標(biāo)準(zhǔn)語(yǔ)法,但由于和大部分其它編程語(yǔ)言的習(xí)慣不太一樣,致使人們有意或無(wú)意地忽略了這些用法。另外,對(duì)于這些用法是否符合 0x00 The Zen of Python 的原則以及該不該廣泛使用也存在很多爭(zhēng)議。例如在我看到的兩本書里(Effective Python VS Write Idiomatic Python),兩位作者就分別對(duì)其持有截然不同的態(tài)度。
循環(huán)中的 else
跟在循環(huán)后面的 else 語(yǔ)句只有在當(dāng)循環(huán)內(nèi)沒(méi)出現(xiàn) break,也就是正常循環(huán)完成時(shí)才會(huì)執(zhí)行。首先我們來(lái)看一個(gè)插入排序法的例子:
from random import randrange def insertion_sort(seq): if len(seq) <= 1: return seq _sorted = seq[:1] for i in seq[1:]: inserted = False for j in range(len(_sorted)): if i < _sorted[j]: _sorted = [*_sorted[:j], i, *_sorted[j:]] inserted = True break if not inserted: _sorted.append(i) return _sorted print(insertion_sort([randrange(1, 100) for i in range(10)]))
[8, 12, 12, 34, 38, 68, 72, 78, 84, 90]
在這個(gè)例子中,對(duì)已排序的 _sorted 元素逐個(gè)與 i 進(jìn)行比較,若 i 比已排序的所有元素都大,則只能排在已排序列表的最后。這時(shí)我們就需要一個(gè)額外的狀態(tài)變量 inserted 來(lái)標(biāo)記完成遍歷循環(huán)還是中途被 break,在這種情況下,我們可以用 else 來(lái)取代這一狀態(tài)變量:
def insertion_sort(seq): if len(seq) <= 1: return seq _sorted = seq[:1] for i in seq[1:]: for j in range(len(_sorted)): if i < _sorted[j]: _sorted = [*_sorted[:j], i, *_sorted[j:]] break else: _sorted.append(i) return _sorted print(insertion_sort([randrange(1, 100) for i in range(10)]))
[1, 10, 27, 32, 32, 43, 50, 55, 80, 94]
我認(rèn)為這是一個(gè)非常酷的做法!不過(guò)要注意的是,除了 break 可以觸發(fā)后面的 else 語(yǔ)句,沒(méi)有循環(huán)的時(shí)候也會(huì):
while False: print("Will never print!") else: print("Loop failed!")
Loop failed!
錯(cuò)誤捕捉中的 else
try...except...else...finally 流程控制語(yǔ)法用于捕捉可能出現(xiàn)的異常并進(jìn)行相應(yīng)的處理,其中 except 用于捕捉 try 語(yǔ)句中出現(xiàn)的錯(cuò)誤;而 else 則用于處理沒(méi)有出現(xiàn)錯(cuò)誤的情況;finally 負(fù)責(zé) try 語(yǔ)句的”善后工作“ ,無(wú)論如何都會(huì)執(zhí)行。可以通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)展示:
def divide(x, y): try: result = x / y except ZeroDivisionError: print("division by 0!") else: print("result = {}".format(result)) finally: print("divide finished!") divide(5,2) print("*"*20) divide(5,0)
result = 2.5 divide finished! ******************** division by 0! divide finished!
當(dāng)然,也可以用狀態(tài)變量的做法來(lái)替代 else:
def divide(x, y): result = None try: result = x / y except ZeroDivisionError: print("division by 0!") if result is not None: print("result = {}".format(result)) print("divide finished!") divide(5,2) print("*"*20) divide(5,0)
result = 2.5 divide finished! ******************** division by 0! divide finished!
總結(jié)
有人覺得 else 的這些用法違反直覺或者是 implicit 而非 explicit,不值得提倡。但我覺得這種”判決“需要依賴具體的應(yīng)用場(chǎng)景以及我們對(duì) Python 的理解,并非一定要對(duì)新人友好的語(yǔ)法才算是 explicit 的。當(dāng)然也不推薦在所有地方都使用這個(gè)語(yǔ)法,for/while...else 最大的缺點(diǎn)在于 else 是需要與 for/file 對(duì)齊的,如果是多層嵌套或者循環(huán)體太長(zhǎng)的情況,就非常不適合用 else(回憶一下游標(biāo)卡尺的梗就知道了:P)。只有在一些簡(jiǎn)短的循環(huán)控制語(yǔ)句中,我們通過(guò) else 擺脫一些累贅的狀態(tài)變量,這才是最 Pythonic 的應(yīng)用場(chǎng)景!
歡迎關(guān)注公眾號(hào) PyHub!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/37827.html
摘要:項(xiàng)目地址我之前翻譯了協(xié)程原理這篇文章之后嘗試用了模式下的協(xié)程進(jìn)行異步開發(fā),確實(shí)感受到協(xié)程所帶來(lái)的好處至少是語(yǔ)法上的。 項(xiàng)目地址:https://git.io/pytips 我之前翻譯了Python 3.5 協(xié)程原理這篇文章之后嘗試用了 Tornado + Motor 模式下的協(xié)程進(jìn)行異步開發(fā),確實(shí)感受到協(xié)程所帶來(lái)的好處(至少是語(yǔ)法上的:D)。至于協(xié)程的 async/await 語(yǔ)法是如...
摘要:項(xiàng)目地址迭代器與生成器迭代器與生成器是中比較常用又很容易混淆的兩個(gè)概念,今天就把它們梳理一遍,并舉一些常用的例子。生成器前面說(shuō)到創(chuàng)建迭代器有種方法,其中第三種就是生成器。 項(xiàng)目地址:https://git.io/pytips 迭代器與生成器 迭代器(iterator)與生成器(generator)是 Python 中比較常用又很容易混淆的兩個(gè)概念,今天就把它們梳理一遍,并舉一些常用的例...
摘要:項(xiàng)目地址所有用過(guò)的人應(yīng)該都看過(guò)下面兩行錯(cuò)誤信息這就是界的錕斤拷今天和接下來(lái)幾期的內(nèi)容將主要關(guān)注中的字符串字節(jié)及兩者之間的相互轉(zhuǎn)換。 項(xiàng)目地址:https://git.io/pytips 所有用過(guò) Python (2&3)的人應(yīng)該都看過(guò)下面兩行錯(cuò)誤信息: UnicodeEncodeError: ascii codec cant encode characters in position...
摘要:項(xiàng)目地址提供兩種內(nèi)置排序方法,一個(gè)是只針對(duì)的原地排序方法,另一個(gè)是針對(duì)所有可迭代對(duì)象的非原地排序方法。 項(xiàng)目地址:https://git.io/pytips Python 提供兩種內(nèi)置排序方法,一個(gè)是只針對(duì) List 的原地(in-place)排序方法 list.sort(),另一個(gè)是針對(duì)所有可迭代對(duì)象的非原地排序方法 sorted()。 所謂原地排序是指會(huì)立即改變被排序的列表對(duì)象,就...
摘要:項(xiàng)目地址作為一種腳本語(yǔ)言,可以非常方便地用于系統(tǒng)尤其是系統(tǒng)命令行工具的開發(fā)。自身也集成了一些標(biāo)準(zhǔn)庫(kù),專門用于處理命令行相關(guān)的問(wèn)題。命令行工具的一般結(jié)構(gòu)標(biāo)準(zhǔn)輸入輸出系統(tǒng)中,一切皆為文件,因此標(biāo)準(zhǔn)輸入輸出可以完全可以看做是對(duì)文件的操作。 項(xiàng)目地址:https://git.io/pytips Python 作為一種腳本語(yǔ)言,可以非常方便地用于系統(tǒng)(尤其是*nix系統(tǒng))命令行工具的開發(fā)。Pyt...
閱讀 819·2021-11-18 10:02
閱讀 2536·2021-11-11 16:54
閱讀 2759·2021-09-02 09:45
閱讀 662·2019-08-30 12:52
閱讀 2790·2019-08-29 14:04
閱讀 2755·2019-08-29 12:39
閱讀 458·2019-08-29 12:27
閱讀 1894·2019-08-26 13:23