我們都知道Python 中else的基本用法是在條件控制語句中的if...elif...else...,但是else 還有兩個其它的用途,一是用於循環的結尾,另一個是用在錯誤處理的try 中。這原本是 Python 的標準語法,但由於和大部分其它程式語言的習慣不太一樣,致使人們有意或無意地忽略了這些用法。另外,對於這些用法是否符合 0×00 The Zen of Python 的原則以及該不該廣泛使用也存在著許多爭議。例如在我看到的兩本書裡(Effective Python VS Write Idiomatic Python),兩位作者就分別對其持有截然不同的態度。
迴圈中的 else
跟在迴圈後面的 else 語句只有在當迴圈內沒出現 break,也就是正常迴圈完成時才會執行。首先我們來看一個插入排序法的例子:
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]
在這個例子中,對已排序的_sorted 元素逐一與i 進行比較,若i比已排序的所有元素都大,則只能排在已排序清單的最後。這時我們就需要一個額外的狀態變數inserted 來標記完成遍歷循環還是中途被break,在這種情況下,我們可以用else 來取代這個狀態變數:
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]
我認為這是一個非常酷的做法!不過要注意的是,除了break 可以觸發後面的else 語句,沒有循環的時候也會:
#while False: print("Will never print!") else: print("Loop failed!") Loop failed!
def pide(x, y): try: result = x / y except ZeropisionError: print("pision by 0!") else: print("result = {}".format(result)) finally: print("pide finished!") pide(5,2) print("*"*20) pide(5,0)
result = 2.5 pide finished! ******************** pision by 0! pide finished!
def pide(x, y): result = None try: result = x / y except ZeropisionError: print("pision by 0!") if result is not None: print("result = {}".format(result)) print("pide finished!") pide(5,2) print("*"*20) pide(5,0)
result = 2.5 pide finished! ******************** pision by 0! pide finished!