"""
从 1 到 100 的整数求和
"""
total = 0for i inrange(1, 101):
total += i
print(total)
上面的代码中,变量 total 的作用是保存累加的结果。在循环的过程中,循环变量 i 的值会从 1 一直取到 100。对于变量 i 的每个取值,我们都执行了 total += i,它相当于 total = total + i,这条语句实现了累加操作。所以,当循环结束,我们输出变量 total 的值,它的值就是从 1 累加到 100 的结果 5050。注意,print(total) 这条语句前是没有缩进的,它不受 for-in 循环的控制,不会重复执行。
我们再来写一个从 1 到 100 偶数求和的代码,如下所示。
"""
从 1 到 100 的偶数求和
"""
total = 0for i inrange(1, 101):
if i % 2 == 0:
total += i
print(total)
说明:上面的 for-in 循环中我们使用了分支结构来判断循环变量 i 是不是偶数。
我们也可以修改 range 函数的参数,将起始值和跨度修改为 2,用更为简单的代码实现从 1 到 100 的偶数求和。
"""
从 1 到 100 的偶数求和
"""
total = 0for i inrange(2, 101, 2):
total += i
print(total)
如果要构造循环结构但是又不能确定循环重复的次数,我们推荐使用 while 循环。while 循环通过布尔值或能产生布尔值的表达式来控制循环,当布尔值或表达式的值为 True 时,循环体(while 语句下方保持相同缩进的代码块)中的语句就会被重复执行,当表达式的值为 False 时,结束循环。
下面我们用 while 循环来实现从 1 到 100 的整数求和,代码如下所示。
"""
从 1 到 100 的整数求和
"""
total = 0
i = 1while i <= 100:
total += i
i += 1print(total)
相较于 for-in 循环,上面的代码我们在循环开始前增加了一个变量 i,我们使用这个变量来控制循环,所以 while 后面给出了 i <= 100 的条件。在 while 的循环体中,我们除了做累加,还需要让变量 i 的值递增,所以我们添加了 i += 1 这条语句,这样 i 的值就会依次取到 1、2、3、……,直到 101。当 i 变成 101 时,while 循环的条件不再成立,代码会离开 while 循环,此时我们输出变量 total 的值,它就是从 1 到 100 求和的结果 5050。
如果要实现从 1 到 100 的偶数求和,我们可以对上面的代码稍作修改。
"""
从 1 到 100 的偶数求和
"""
total = 0
i = 2while i <= 100:
total += i
i += 2print(total)
break 和 continue
我们再来看一个极端的场景,把 while 循环的条件直接设置为布尔值 True,还是从 1 到 100 的偶数求和。
"""
从 1 到 100 的偶数求和
"""
total = 0
i = 2whileTrue:
total += i
i += 2if i > 100:
breakprint(total)
上面的代码中使用 while True 构造了一个条件恒成立的循环,也就意味着如果不做特殊处理,循环是不会结束的,这也就是常说的'死循环'。为了在 i 的值超过 100 后让循环停下来,我们使用了 break 关键字,它的作用是终止循环结构的执行。需要注意的是,break 只能终止它所在的那个循环,这一点在使用嵌套循环结构时需要引起注意,后面我们会讲到什么是嵌套的循环结构。
"""
输入一个大于 1 的正整数判断它是不是素数
"""
num = int(input('请输入一个正整数:'))
end = int(num ** 0.5)
is_prime = Truefor i inrange(2, end + 1):
if num % i == 0:
is_prime = Falsebreakif is_prime:
print(f'{num}是素数')
else:
print(f'{num}不是素数')
说明:上面的代码中我们用了布尔型的变量 is_prime,我们先将它赋值为 True,假设 num 是一个素数;接下来,我们在 2 到 num ** 0.5 的范围寻找 num 的因子,如果找到了 num 的因子,那么它一定不是素数,此时我们将 is_prime 赋值为 False,同时使用 break 关键字终止循环结构;最后,我们根据 is_prime 的值是 True 还是 False 来给出不同的输出。
例子 2:最大公约数
要求:输入两个大于 0 的正整数,求两个数的最大公约数。
提示:两个数的最大公约数是两个数的公共因子中最大的那个数。
"""
输入两个正整数计算它们的最大公约数
"""
x = int(input('x = '))
y = int(input('y = '))
for i inrange(x, 0, -1):
if x % i == 0and y % i == 0:
print(f'最大公约数:{i}')
break
说明:上面代码中 for-in 循环的循环变量值是从大到小的,这样我们找到的能够同时整除 x 和 y 的因子 i,就是 x 和 y 的最大公约数,此时我们用 break 终止循环。如果 x 和 y 互质,那么循环会执行到 i 变成 1,因为 1 是所有正整数的因子,此时 x 和 y 的最大公约数就是 1。
用上面代码的找最大公约数在执行效率是有问题的。假如 x 的值是 999999999998,y 的值是 999999999999,很显然两个数是互质的,最大公约数为 1。但是我们使用上面的代码,循环会重复 999999999998 次,这通常是难以接受的。我们可以使用欧几里得算法(辗转相除法)来找最大公约数,它能帮我们更快的得到想要的结果,代码如下所示。
"""
输入两个正整数计算它们的最大公约数
"""
x = int(input('x = '))
y = int(input('y = '))
while y % x != 0:
x, y = y % x, x
print(f'最大公约数:{x}')
说明:解决问题的方法和步骤可以称之为算法,对于同一个问题,我们可以设计出不同的算法,不同的算法在存储空间的占用和执行效率上都会存在差别,而这些差别就代表了算法的优劣。大家可以对比上面的两段代码,体会一下为什么我们说欧几里得算法是更好的选择。上面的代码中 x, y = y % x, x 语句表示将 y % x 的值赋给 x,将 x 原来的值赋给 y。
设置断点:在 IDE(如 PyCharm 或 VS Code)中设置断点,单步执行循环代码,观察每一步的状态。
检查边界条件:特别注意循环的起始值和终止值,确保没有遗漏或越界的情况,尤其是涉及 range 函数时。
总结
学会了 Python 中的分支结构和循环结构,我们就可以解决很多实际的问题了。通过这节课的学习,大家应该已经知道了可以用 for 和 while 关键字来构造循环结构。如果事先知道循环结构重复的次数,我们通常使用 for 循环;如果循环结构的重复次数不能确定,可以用 while 循环。此外,我们可以在循环结构中使用 break 终止循环,也可以在循环结构中使用 continue 关键字让循环结构直接进入下一轮次。