Python中的else详解
我们都知道 Python 中else的基本⽤法是在条件控制语句中的 if...,但是 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:
while语句怎么用在python中
print("Loop failed!")
Loop failed!
错误捕捉中的 else
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 的。当然也不推荐在所有地⽅都使⽤这个语
法,lse 最⼤的缺点在于 else 是需要与 for/file 对齐的,如果是多层嵌套或者循环体太长的情
况,就⾮常不适合⽤else(回忆⼀下游标卡尺的梗就知道了:P)。只有在⼀些简短的循环控制语句中,我们通过 else 摆脱⼀些累赘的状态变量,这才是最 Pythonic 的应⽤场景!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论