翻譯自 https://s16h.medium.com/the-forgotten-optional-else-in-python-loops-90d9c465c830
本文介紹Python的 for-else
和 while-else
語法,Python 中最少被使用和經常被誤解的特性之一。
Python中的for
循環和while
循環都有一個可選的 else
套件(類似於if
語句和try
語句),如果循環正常結束,那麼就會執行該else套件。換句話說,如果我們不以任何非自然的方式(break
、return
或拋出異常)退出循環,else
套件就會被執行。即,沒有 break
語句,沒有 return
語句,或者在循環中沒有引發異常
。
看一個簡單的例子:
In [1]: for i in range(5):
...: print(i)
...: else:
...: print("Iterated over everything :)")
...:
0
1
2
3
4
Iterated over everything :)
在上面的代碼中,我們遍歷range(5)
並打印每個數字。因為我們讓循環正常完成,所以 else
套件也會被執行,並且Iterated over everything :)
被打印出來。相反,如果我們停止循環,比如使用 break
語句,那麼 else
套件將不會被執行:
In [2]: for i in range(5):
...: if i == 2:
...: break
...: print(i)
...: else:
...: print("Iterated over everything :)")
...:
0
1
注意,即使循環所迭代的序列為空,else
套件也會被執行; 畢竟,循環仍然正常地完成:
In [3]: for i in []:
...: print(i)
...: else:
...: print("Iterated over everything :)")
...:
Iterated over everything :)
另外,我們不要忘記,以上這些也適用於 while-else
:
In [4]: i = 0
In [5]: while i <= 5:
...: i += 1
...: print(i)
...: else:
...: print('Yep')
...:
1
2
3
4
5
6
Yep
else
子句在循環中的常見使用情況是實現搜索循環。
假設你正在搜索一個滿足特定條件的條目,並且需要執行額外的處理,或者如果沒有找到可接受的值,則引發一個錯誤:
for x in data:
if meet_condation(x):
break
else:
# raise error or do addition processing
如果沒有 else
子句,則需要設置一個標志,然後在稍後檢查該標志,以查看是否有任何值滿足下列條件:
condition_is_met = False
for x in data:
if meets_condition(x):
condition_is_met = True
if not condition_is_met:
# raise error or do additional processing
這其實沒什麼大不了的,這就是你在其他許多語言中必須要做的事情。
但是,與 Python 的許多其他特性一樣,else
子句可以產生更優雅和 Pythonic 的代碼。可以說,在上面的例子中,使用它可以使代碼更加 The Zen of Python-friendly。
沒有一種情況是你別無選擇,只能在循環中使用 else
子句。你總是可以使用 flag 標志等方法,但 else
子句通常可以使代碼更加優雅和可讀。有人可能會認為這是 Pythonic 的,它使意圖更清晰,而其他人可能會認為它是混亂和多余的!