for-else
语法
你是否见过这个语法?
for i in xxx:
pass
else:
pass
是不是一脸懵逼!!!啊哈哈哈~
事实上,在 Python 中,else
不仅可以与 if
搭配使用,还可以与 for
结合。(想不到吧!🤣🤣)
我们先来看一个例子:
>>> for i in range(5):
... print(i)
... else:
... print("hello?")
...
0
1
2
3
4
hello?
可以看到,在for
正常结束后,else
中的语句被执行了。
>>> for i in range(5):
... print(i)
... if i == 3:
... break
... else:
... print("hello?")
...
0
1
2
3
在这个例子当中,i==3
的时候退出了循环,然后else
当中的语句没有执行。
所以,for-else
的语法其实很简单:如果for
循环正常结束,else
中的语句正常执行。如果 for
循环中有 break
字段等导致 for
循环没有正常执行完毕,那么 else
中的内容就不会执行。
一句话说清楚:**else**
里面的语句是否执行,取决于 **for**
循环能否正常执行完毕。
else
语法解决的问题是:一般for
循环结束后,我们无法直接知道for
循环是提前跳出的,还是走完整个循环结束的,需要通过额外的if
语句进行判断,而for-else
则很简单的解决了这个问题。
for-else
用途
主要两个用途:
for-else
语句在一些场景上可以减少代码量,避免使用**flag**
。**for**
循环能否正常执行完毕。
有个常见的构造是跑一个循环,并查找一个元素。如果这个元素被找到了,我们使用 break
来中断这个循环。有两个场景会让循环停下来。
- 第一个是当一个元素被找到,
break
被触发。 - 第二个场景是循环结束。
我们也许想知道是其中哪一个是导致循环完成的原因。一个方法是先设置一个标记flag
,然后在循环结束时打上标记。另一个就是使用 for-else
从句。这就是 for/else 循环的基本结构:
for item in container:
if search_something(item):
# Found it!
process(item)
break
else:
not_found_in_container() # Didn't find anything..
官方文档里给出了这样一个例子:
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, '*', n / x)
break
它会找出2到10之间的数字的因子。现在,我们可以加上一个附加的else
语句块,来找出质数,并且告打印出来:
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, '*', n / x)
break
else:
print(n, 'is a prime number') # loop fell through without finding a factor
同样,拓展一下,现在要求100以内的素数之和,就可以这样做:
>>> total_sum = 0
>>> for n in range(2, 100):
... for i in range(2, n):
... if n % i == 0:
... break
... else:
... total_sum += n
>>> print(total_sum)
1060
再来一个例子:从一个二维数组数组中是否有某个数,并给出第一次出现的位置。
为了及时结束查找,我们一般的做法是设置一个flag
,如果找到就把flag
设为true
,否则为false
。如果使用for-else
就能避免使用flag
:
>>> l = [range(5 * i, 5 * i + 5) for i in range(5)]
>>> a = 20 # 要查找的数
>>> for i, x in enumerate(l):
... for j, y in enumerate(x):
... if y == a:
... loc = (i, j)
... break
... else:
... continue
... print('Find it! And the loc is: ', loc)
... break
...
Find it! And the loc is: (4, 0)