嵌套循环

下图是for循环的一般形式
python-for循环一般形式
在循环体block中,又是一片全新的天地,你可以写任何你想写的代码,当然包括for循环,应该这样讲,嵌套循环不是什么特殊形式,只是对于初学者来说,嵌套循环不容易被理解,因此,我专门写一篇教程来讲解。

1. 两层嵌套for循环

for i in range(3):
    for j in range(3):
        print(i, j)

非常简单的两层嵌套for循环,不执行代码,如果可以直接说出程序的执行结果,那么可以证明你对于for循环的理解很到位,很透彻。如果不能,那么就请认真的听过讲解,程序的输出结果是

0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2

程序由上而下执行,因此先要执行最外层的循环 for i in range(3) ,循环会进行3轮,先来看第1轮,第一轮循环时,i = 0,进入循环体执行代码,循环体里的代码如下所示

for j in range(3):
    print(i, j)

这个时候,你就不要管最外层的循环了,把精力放在这个循环上,内层的循环也执行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):
    print(i, j)

得了,内层循环还得3轮,3轮过后,输出

1 0
1 1
1 2

随后,开始外层循环第3轮,最终输出

2 0
2 1
2 2

2. 3层嵌套循环

无非是比2层多出一层而已,没有什么特殊的,只要准确理解for循环,不管是两层,还是三层,其实都一样。

lst1 = [2, 1, 4, 6, 5]
lst2 = [3, 2, 7, 4]
lst3 = [4, 5, 2, 3]

从这3个列表里各取出一个数,3个数的和等于10的组合有多少,请写代码输出这些组合,不考虑重复性

lst1 = [2, 1, 4, 6, 5]
lst2 = [3, 2, 7, 4]
lst3 = [4, 5, 2, 3]

for i in lst1:
    for j in lst2:
        for k in lst3:
            if i + j + k == 10:
                print((i, j, k))

程序输出结果

(2, 3, 5)
(2, 4, 4)
(1, 7, 2)
(1, 4, 5)
(4, 3, 3)
(4, 2, 4)
(4, 4, 2)
(6, 2, 2)
(5, 3, 2)
(5, 2, 3)

你可以看到,但循环达到3层时,代码的缩进更多,更加难以阅读,不仅如此,3层嵌套循环会导致算法复杂度快速变大,导致性能无法满足要求,因此,你要尽量避免写出3层嵌套循环。

3. 嵌套循环的终止

如果循环只有一层,使用break就可以终止循环,但如果循环有两层,事情就变得麻烦
已知有两个列表

lst1 = [2, 7, 4, 6, 5]
lst2 = [3, 2, 7, 4]

请编写程序,从两个列表里各取出一个数,使其和为10,这种组合有多个,但要求找到一个即可,你应该已经想到了,一旦找到这种组合,就使用break语句终止循环,请你判断下面的代码能否符合要求。

lst1 = [2, 7, 4, 6, 5]
lst2 = [3, 2, 7, 4]

for i in lst1:
    for j in lst2:
        if i + j == 10:
            print((i, j))
            break

程序实际输出结果是

(7, 3)
(6, 4)

明明使用了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]
lst2 = [3, 2, 7, 4]

stop = False
for i in lst1:
    for j in lst2:
        if i + j == 10:
            print((i, j))
            stop = True
            break

    if stop:
        break

借助变量stop来标识是否已经找到了一组组合,如果找到了,则将stop设置为True,注意看if stop 的缩进和 for j in lst2 是相同的,当内层循环结束后,就会执行这个if判断,满足条件后,再次执行break,这个break所在的循环是for i in lst1 , 最终外层循环也被终止。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案