for-else 语法

你是否见过这个语法?

  1. for i in xxx:
  2. pass
  3. else:
  4. pass

是不是一脸懵逼!!!啊哈哈哈~

事实上,在 Python 中,else不仅可以与 if搭配使用,还可以与 for结合。(想不到吧!🤣🤣)

我们先来看一个例子:

  1. >>> for i in range(5):
  2. ... print(i)
  3. ... else:
  4. ... print("hello?")
  5. ...
  6. 0
  7. 1
  8. 2
  9. 3
  10. 4
  11. hello?

可以看到,在for正常结束后,else中的语句被执行了。

  1. >>> for i in range(5):
  2. ... print(i)
  3. ... if i == 3:
  4. ... break
  5. ... else:
  6. ... print("hello?")
  7. ...
  8. 0
  9. 1
  10. 2
  11. 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 循环的基本结构:

  1. for item in container:
  2. if search_something(item):
  3. # Found it!
  4. process(item)
  5. break
  6. else:
  7. not_found_in_container() # Didn't find anything..

官方文档里给出了这样一个例子:

  1. for n in range(2, 10):
  2. for x in range(2, n):
  3. if n % x == 0:
  4. print(n, 'equals', x, '*', n / x)
  5. break

它会找出2到10之间的数字的因子。现在,我们可以加上一个附加的else语句块,来找出质数,并且告打印出来:

  1. for n in range(2, 10):
  2. for x in range(2, n):
  3. if n % x == 0:
  4. print(n, 'equals', x, '*', n / x)
  5. break
  6. else:
  7. print(n, 'is a prime number') # loop fell through without finding a factor

同样,拓展一下,现在要求100以内的素数之和,就可以这样做:

  1. >>> total_sum = 0
  2. >>> for n in range(2, 100):
  3. ... for i in range(2, n):
  4. ... if n % i == 0:
  5. ... break
  6. ... else:
  7. ... total_sum += n
  8. >>> print(total_sum)
  9. 1060

再来一个例子:从一个二维数组数组中是否有某个数,并给出第一次出现的位置。

为了及时结束查找,我们一般的做法是设置一个flag,如果找到就把flag设为true,否则为false。如果使用for-else就能避免使用flag

  1. >>> l = [range(5 * i, 5 * i + 5) for i in range(5)]
  2. >>> a = 20 # 要查找的数
  3. >>> for i, x in enumerate(l):
  4. ... for j, y in enumerate(x):
  5. ... if y == a:
  6. ... loc = (i, j)
  7. ... break
  8. ... else:
  9. ... continue
  10. ... print('Find it! And the loc is: ', loc)
  11. ... break
  12. ...
  13. Find it! And the loc is: (4, 0)

参考