2.13.4 循环的终止
循环让我们可以遍历一个集合。在很多情况下,遍历的目的是搜索和过滤某些特定的情况,在条件满足的时候,我们会结束循环。结束循环有一些细分的情况,对应的代码逻辑也会有差异,我们来逐一分析。
质数(prime number)是指一类特别的正整数,除了1和该数自身以外,它们不能被其他自然数整除。用代码来判断一个数是不是质数,最简单的思路就是用循环。
num = 102 print("Is '{}' a prime number?".format(num)) is_prime_number = True for dividend in range(2, num): if num % dividend == 0: print(' - {}'.format(dividend)) is_prime_number = False print(is_prime_number)
执行结果如下:
Is '102' a prime number? - 2 - 3 - 6 - 17 - 34 - 51 False
这段代码可以准确判断出102不是质数,因为它可以分别被2、3、6、17、34、51整除。要证明一个数不是质数,我们只需要找到一个可以整除它的数(除了1和它自身)就足够了。在找到了第一个这样的被除数以后,循环就没有必要继续了,在这种情况下,我们应该用break把后续的循环全部取消。
num = 102 print("Is '{}' a prime number?".format(num)) is_prime_number = True for dividend in range(2, num): if num % dividend == 0: is_prime_number = False print(' - {}'.format(dividend)) break print(is_prime_number)
执行结果如下:
Is '102' a prime number? - 2 False
以上代码比较凌乱,我们可以设计一个函数,专门用于判断指定的数是不是质数。
def is_prime_number(num): is_prime_number = True for dividend in range(2, num): if num % dividend == 0: is_prime_number = False break return is_prime_number
重构后的函数也可以工作,只是在这种简单的循环函数中,我们可以用return来让代码更简化。
def is_prime_number(num): for dividend in range(2, num): if num % dividend == 0: return False return True
在以上范例中,我们不再创建额外的布尔类型变量,而是在发现第一个这样的整除数时,函数就返回布尔值False,表明这不是质数。如果整个循环都结束了都没有找到这样的整除数,函数就返回True,表明这是一个质数。
严格来说,return关键字并不是专门为循环设计的,而是为函数设计的,但是在一些包含循环逻辑的函数中,我们可以用return“立刻返回”的特性来结束循环。
基于以上代码,我们来看一个新的问题:有一个整数list,需要把其中的所有质数挑选出来,打印在屏幕上。很显然,我们需要用到循环逻辑,在遍历过程中,如果某个数不是质数,不需要对它做进一步处理,但是后续的循环还要继续,还要判断list中的其他数是不是质数。在这种情况下,我们需要用到continue关键字。
numbers = [101, 102, 103, 200, 29, 31, 301] for num in numbers: if not is_prime_number(num): continue print('{} is prime number'.format(num))
一次循环迭代涉及的逻辑很可能不止一个步骤。在循环迭代中,continue表示跳过本次循环迭代的后续步骤开始下一个循环迭代。
接下来,我们看一个更复杂的问题。给定一个如下所示的二维list。
number_matrix = [ [101, 102, 103], [787, 773, 751], [301, 307, 317], [721, 723, 743] ]
这个二维list的每一个元素都是一个整型数list,我们想把其中每个元素都是质数的子list挑选出来,这需要用到多重循环。
def get_prime_lists(number_lists): prime_lists = [] for numbers in number_lists: non_prime_number_found = False for num in numbers: if not is_prime_number(num): print(' - {} is not a prime number in {}'.format(num, numbers)) non_prime_number_found = True break if non_prime_number_found: continue prime_lists.append(numbers) return prime_lists
执行结果如下:
- 102 is not a prime number in [101, 102, 103] - 301 is not a prime number in [301, 307, 317] - 721 is not a prime number in [721, 723, 743] [787, 773, 751]
从结果来分析程序逻辑,我们可以看到:在多重循环中使用的break语句,只会结束它直接所在的那一层循环,不会影响更外层的循环逻辑。
以上代码主要演示的是循环的控制,对于质数的判断逻辑不够严谨,读者可以自行改进。