嵌套循环
下图是for循环的一般形式
在循环体block中,又是一片全新的天地,你可以写任何你想写的代码,当然包括for循环,应该这样讲,嵌套循环不是什么特殊形式,只是对于初学者来说,嵌套循环不容易被理解,因此,我专门写一篇教程来讲解。
1. 两层嵌套for循环
for i in range(3): |
非常简单的两层嵌套for循环,不执行代码,如果可以直接说出程序的执行结果,那么可以证明你对于for循环的理解很到位,很透彻。如果不能,那么就请认真的听过讲解,程序的输出结果是
0 0 |
程序由上而下执行,因此先要执行最外层的循环 for i in range(3) ,循环会进行3轮,先来看第1轮,第一轮循环时,i = 0,进入循环体执行代码,循环体里的代码如下所示
for j in range(3): |
这个时候,你就不要管最外层的循环了,把精力放在这个循环上,内层的循环也执行3轮,把上面代码视为一个整体,只有当这个整体执行结束时才能开始外层循环的下一轮。
第1轮
j = 0, 进入循环体执行print(i, j),此时i=0,j=0,输出结果是0 0 |
第2轮
j = 1, 进入循环体执行print(i, j),此时i=0,j=1,输出结果是0 1 |
第3轮
j = 2, 进入循环体执行print(i, j),此时i=0,j=2,输出结果是0 2 |
3轮之后,内层循环结束,此时开始外层循环的第2轮,i=1,老规矩,进入循环体,而循环体里的代码还是
for j in range(3): |
得了,内层循环还得3轮,3轮过后,输出
1 0 |
随后,开始外层循环第3轮,最终输出
2 0 |
2. 3层嵌套循环
无非是比2层多出一层而已,没有什么特殊的,只要准确理解for循环,不管是两层,还是三层,其实都一样。
lst1 = [2, 1, 4, 6, 5] |
从这3个列表里各取出一个数,3个数的和等于10的组合有多少,请写代码输出这些组合,不考虑重复性
lst1 = [2, 1, 4, 6, 5] |
程序输出结果
(2, 3, 5) |
你可以看到,但循环达到3层时,代码的缩进更多,更加难以阅读,不仅如此,3层嵌套循环会导致算法复杂度快速变大,导致性能无法满足要求,因此,你要尽量避免写出3层嵌套循环。
3. 嵌套循环的终止
如果循环只有一层,使用break就可以终止循环,但如果循环有两层,事情就变得麻烦
已知有两个列表
lst1 = [2, 7, 4, 6, 5] |
请编写程序,从两个列表里各取出一个数,使其和为10,这种组合有多个,但要求找到一个即可,你应该已经想到了,一旦找到这种组合,就使用break语句终止循环,请你判断下面的代码能否符合要求。
lst1 = [2, 7, 4, 6, 5] |
程序实际输出结果是
(7, 3) |
明明使用了break,为什么还是输出了两个组合呢?回想一下break的作用,break终止当前所在的循环,也就是说当break被执行时,终止的是for j in lst2 这层循环,而外层的for i in lst1 却并没有终止。输出(7, 3)之后,外层的循环继续执行,当i=6时,进入循环体执行for j in lst2 这层循环,最终输出了(6, 4)。
那么,该如何在获得一个组合后终止这两层for循环呢,看下面的示例代码
lst1 = [2, 7, 4, 6, 5] |
借助变量stop来标识是否已经找到了一组组合,如果找到了,则将stop设置为True,注意看if stop 的缩进和 for j in lst2 是相同的,当内层循环结束后,就会执行这个if判断,满足条件后,再次执行break,这个break所在的循环是for i in lst1 , 最终外层循环也被终止。