Python循环中被遗忘的else选项
翻译自 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 的,它使意图更清晰,而其他人可能会认为它是混乱和多余的!