Python 中else的基本用法是在條件控制語句迴圈
我們都知道 Python 中else的基本用法是在條件控制語句中的 if...elif...else...,但是 else 還有兩個其它的用途,一是用於迴圈的結尾,另一個是用在錯誤處理的 try 中。這原本是 Python 的標準語法,但由於和大部分其它程式語言的習慣不太一樣,致使人們有意或無意地忽略了這些用法。另外,對於這些用法是否符合 0×00 The Zen of Python 的原則以及該不該廣泛使用也存在很多爭議。例如在我看到的兩本書裡(Effective Python VS Write Idiomatic Python),兩位作者就分別對其持有截然不同的態度。QANDA.REN程式設計
迴圈中的 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!
錯誤捕捉中的 else
try...except...else...finally 流程控制語法用於捕捉可能出現的異常並進行相應的處理,其中 except 用於捕捉 try 語句中出現的錯誤;而 else 則用於處理沒有出現錯誤的情況;finally 負責 try 語句的”善後工作“ ,無論如何都會執行。可以透過一個簡單的例子來展示:
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!
當然,也可以用狀態變數的做法來替代 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!
總結
有人覺得 else 的這些用法違反直覺或者是 implicit 而非 explicit,不值得提倡。但我覺得這種”判決“需要依賴具體的應用場景以及我們對 Python 的理解,並非一定要對新人友好的語法才算是 explicit 的。當然也不推薦在所有地方都使用這個語法,for/while...else 最大的缺點在於 else 是需要與 for/file 對齊的,如果是多層巢狀或者迴圈體太長的情況,就非常不適合用 else(回憶一下游標卡尺的梗就知道了:P)。只有在一些簡短的迴圈控制語句中,我們透過 else 擺脫一些累贅的狀態變數,這才是最 Pythonic 的應用場景!
迴圈中的 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!
錯誤捕捉中的 else
try...except...else...finally 流程控制語法用於捕捉可能出現的異常並進行相應的處理,其中 except 用於捕捉 try 語句中出現的錯誤;而 else 則用於處理沒有出現錯誤的情況;finally 負責 try 語句的”善後工作“ ,無論如何都會執行。可以透過一個簡單的例子來展示:
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!
當然,也可以用狀態變數的做法來替代 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!
總結
有人覺得 else 的這些用法違反直覺或者是 implicit 而非 explicit,不值得提倡。但我覺得這種”判決“需要依賴具體的應用場景以及我們對 Python 的理解,並非一定要對新人友好的語法才算是 explicit 的。當然也不推薦在所有地方都使用這個語法,for/while...else 最大的缺點在於 else 是需要與 for/file 對齊的,如果是多層巢狀或者迴圈體太長的情況,就非常不適合用 else(回憶一下游標卡尺的梗就知道了:P)。只有在一些簡短的迴圈控制語句中,我們透過 else 擺脫一些累贅的狀態變數,這才是最 Pythonic 的應用場景!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30117771/viewspace-2087131/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python條件語句與迴圈Python
- Python if else條件語句Python
- Python-條件語句和迴圈語句Python
- SqlServer中迴圈和條件語句SQLServer
- Python if else條件語句詳解Python
- Python學習筆記3(條件語句+迴圈語句)Python筆記
- 條件迴圈語句組成了Python程式碼的骨架Python
- Mysql儲存過程 變數,條件,迴圈語句用法MySql儲存過程變數
- 在Linux中,shell指令碼中的條件語句和迴圈結構是什麼?Linux指令碼
- python-條件控制(if語句)Python
- Python 入門 :基本條件語句Python
- AWK if(條件)語句與迴圈簡介
- javascript新手入門之條件語句,迴圈JavaScript
- Python的迴圈語句Python
- Go:條件控制語句Go
- C 語言教程:條件和 if...else 語句
- python中if語句的用法及if-else結構的使用Python
- Go_ if else語句 ,,迴圈,,switch,,陣列Go陣列
- JS-13 條件語句之if...elseJS
- 流程控制、 迴圈語句
- JavaScript 流程控制語句詳解:if語句、switch語句、while迴圈、for迴圈等JavaScriptWhile
- C語言中迴圈語句while 中判斷條件出現 || 和 && 的區別C語言While
- Python 迴圈語句的使用Python
- PL/SQL 條件控制語句SQL
- php中有哪些迴圈控制語句PHP
- python 中的 for-else 和 while-else 語句PythonWhile
- oracle中的條件語句Oracle
- Python中if else語句出錯Python
- 【Python基礎】for迴圈語句Python
- 『無為則無心』Python基礎 — 15、Python流程控制語句(for迴圈語句)Python
- Python 基礎起步 (九) 條件語句 if elif else 其實很簡單Python
- 【分支流程控制語句、迴圈流程控制語句】的學習
- 『無為則無心』Python基礎 — 13、Python流程控制語句(條件語句)Python
- python條件判斷與迴圈Python
- Python 中的for,if-else和while語句PythonWhile
- python迴圈語句判斷的使用Python
- 寫給.NET開發者的Python教程(三):運算子、條件判斷和迴圈語句Python
- python04: while迴圈語句 break continue for in 迴圈PythonWhile
- sql宣告變數,及if -else語句、while語句的用法SQL變數While