CodeRoadMap
路线图学习路径文章题库资源社区

浏览

首页路线图学习路径知识库题库文章资源社区我的学习
CodeRoadMap

中文编程学习导航:路线图、讲义与题库,进度可同步。

路线图学习路径文章题库社区

© 2026 CodeRoadMap

津ICP备2026012044号-1|coderoadmap@126.com
首页/Python 100 天/06.循环结构

课程目录

  1. 0101.初识Python
  2. 0202.第一个Python程序
  3. 0303.Python语言中的变量
  4. 0404.Python语言中的运算符
  5. 0505.分支结构
  6. 0606.循环结构
  7. 0707.分支和循环结构实战
  8. 0808.常用数据结构之列表-1
  9. 0909.常用数据结构之列表-2
  10. 1010.常用数据结构之元组
  11. 1111.常用数据结构之字符串
  12. 1212.常用数据结构之集合
  13. 1313.常用数据结构之字典
  14. 1414.函数和模块
  15. 1515.函数应用实战
  16. 1616.函数使用进阶
  17. 1717.函数高级应用
  18. 1818.面向对象编程入门
  19. 1919.面向对象编程进阶
  20. 2020.面向对象编程应用
  21. 2121.文件读写和异常处理
  22. 2222.对象的序列化和反序列化
  23. 2323.Python读写CSV文件
  24. 2424.Python读写Excel文件-1
  25. 2525.Python读写Excel文件-2
  26. 2626.Python操作Word和PowerPoint文件
  27. 2727.Python操作PDF文件
  28. 2828.Python处理图像
  29. 2929.Python发送邮件和短信
  30. 3030.正则表达式的应用
  31. 3131.Python语言进阶
  32. 3232-33.Web前端入门
  33. 3334-35.玩转Linux操作系统
  34. 3436.关系型数据库和MySQL概述
  35. 3537.SQL详解之DDL
  36. 3638.SQL详解之DML
  37. 3739.SQL详解之DQL
  38. 3840.SQL详解之DCL
  39. 3941.MySQL新特性
  40. 4042.视图、函数和过程
  41. 4143.索引
  42. 4244.Python接入MySQL数据库
  43. 4345.Hive实战
  44. 4446.Django快速上手
  45. 4547.深入模型
  46. 4648.静态资源和Ajax请求
  47. 4749.Cookie和Session
  48. 4850.制作报表
  49. 4951.日志和调试工具栏
  50. 5052.中间件的应用
  51. 5153.前后端分离开发入门
  52. 5254.RESTful架构和DRF入门
  53. 5355.RESTful架构和DRF进阶
  54. 5456.使用缓存
  55. 5557.接入三方平台
  56. 5658.异步任务和定时任务
  57. 5759.单元测试
  58. 5860.项目上线
  59. 5961.网络数据采集概述
  60. 6062.用Python获取网络资源-1
  61. 6162.用Python解析HTML页面-2
  62. 6263.并发编程在爬虫中的应用
  63. 6363.Python中的并发编程-1
  64. 6463.Python中的并发编程-2
  65. 6563.Python中的并发编程-3
  66. 6664.使用Selenium抓取网页动态内容
  67. 6765.爬虫框架Scrapy简介
  68. 6866.数据分析概述
  69. 6967.环境准备
  70. 7068.NumPy的应用-1
  71. 7169.NumPy的应用-2
  72. 7270.NumPy的应用-3
  73. 7371.NumPy的应用-4
  74. 7472.深入浅出pandas-1
  75. 7573.深入浅出pandas-2
  76. 7674.深入浅出pandas-3
  77. 7775.深入浅出pandas-4
  78. 7876.深入浅出pandas-5
  79. 7977.深入浅出pandas-6
  80. 8078.数据可视化-1
  81. 8179.数据可视化-2
  82. 8280.数据可视化-3
  83. 8381.浅谈机器学习
  84. 8482.k最近邻算法
  85. 8583.决策树和随机森林
  86. 8684.朴素贝叶斯算法
  87. 8785.回归模型
  88. 8886.K-Means聚类算法
  89. 8987.集成学习算法
  90. 9088.神经网络模型
  91. 9189.自然语言处理入门
  92. 9290.机器学习实战
  93. 9391.团队项目开发的问题和解决方案
  94. 9492.Docker容器技术详解
  95. 9593.MySQL性能优化
  96. 9694.网络API接口设计
  97. 9795.使用Django开发商业项目
  98. 9896.软件测试和自动化测试
  99. 9997.电商网站技术要点剖析
  100. 10098.项目部署上线和性能调优
  101. 10199.面试中的公共问题
  102. 102100.补充内容
第 06 课1 天

06.循环结构

我们在写程序的时候,极有可能遇到需要重复执行某条或某些指令的场景,例如我们需要每隔1秒钟在屏幕上输出一次“hello, world”并持续输出一个小时。如下所示

课程内容

循环结构

我们在写程序的时候,极有可能遇到需要重复执行某条或某些指令的场景,例如我们需要每隔1秒钟在屏幕上输出一次“hello, world”并持续输出一个小时。如下所示的代码可以完成一次这样的操作,如果要持续输出一个小时,我们就需要把这段代码写3600遍,你愿意这么做吗?

import time

print('hello, world')
time.sleep(1)

说明:Python 内置time模块的sleep函数可以实现程序的休眠,参数1表示休眠的秒数,可以使用int或float类型,例如0.05表示50毫秒。关于函数和模块的知识,我们在后续的课程中会为大家讲解。

为了应对上述场景中的问题,我们可以在 Python 程序中使用循环结构。所谓循环结构,就是程序中控制某条或某些指令重复执行的结构。有了这样的结构,刚才的代码就不需要写 3600 遍,而是写一遍然后放到循环结构中重复 3600 次。在 Python 语言中构造循环结构有两种做法,一种是for-in循环,另一种是while循环。

for-in循环

如果明确知道循环执行的次数,我们推荐使用for-in循环,例如上面说的那个重复 3600 次的场景,我们可以用下面的代码来实现。 注意,被for-in循环控制的代码块也是通过缩进的方式来构造,这一点跟分支结构中构造代码块的做法是一样的。我们被for-in循环控制的代码块称为循环体,通常循环体中的语句会根据循环的设定被重复执行。

"""
每隔1秒输出一次“hello, world”,持续1小时

Author: 骆昊
Version: 1.0
"""
import time

for i in range(3600):
    print('hello, world')
    time.sleep(1)

需要说明的是,上面代码中的range(3600)可以构造出一个从0到3599的范围,当我们把这样一个范围放到for-in循环中,就可以通过前面的循环变量i依次取出从0到3599的整数,这就会让for-in代码块中的语句重复 3600 次。当然,range的用法非常灵活,下面的清单给出了使用range函数的例子:

  • range(101):可以用来产生0到100范围的整数,需要注意的是取不到101。
  • range(1, 101):可以用来产生1到100范围的整数,相当于是左闭右开的设定,即[1, 101)。
  • range(1, 101, 2):可以用来产生1到100的奇数,其中2是步长(跨度),即每次递增的值,101取不到。
  • range(100, 0, -2):可以用来产生100到1的偶数,其中-2是步长(跨度),即每次递减的值,0取不到。
  • 大家可能已经注意到了,上面代码的输出操作和休眠操作都没有用到循环变量i,对于不需要用到循环变量的for-in循环结构,按照 Python 的编程惯例,我们通常把循环变量命名为_,修改后的代码如下所示。虽然结果没什么变化,但是这样写显得你更加专业,逼格瞬间拉满。

    """
    每隔1秒输出一次“hello, world”,持续1小时
    
    Author: 骆昊
    Version: 1.1
    """
    import time
    
    for _ in range(3600):
        print('hello, world')
        time.sleep(1)
    

    上面的代码要执行一个小时,如果想提前结束程序,在 PyCharm 中可以点击运行窗口上的停止按钮,如下图所示。如果在命令提示符或终端中运行代码,可以使用组合键ctrl+c来终止程序。

    下面,我们用for-in循环实现从 1 到 100 的整数求和,即 $\small{\sum_{n=1}^{100}{n}}$ 。

    """
    从1到100的整数求和
    
    Version: 1.0
    Author: 骆昊
    """
    total = 0
    for i in range(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的偶数求和
    
    Version: 1.0
    Author: 骆昊
    """
    total = 0
    for i in range(1, 101):
        if i % 2 == 0:
            total += i
    print(total)
    

    说明:上面的for-in循环中我们使用了分支结构来判断循环变量i是不是偶数。

    我们也可以修改range函数的参数,将起始值和跨度修改为2,用更为简单的代码实现从 1 到 100 的偶数求和。

    """
    从1到100的偶数求和
    
    Version: 1.1
    Author: 骆昊
    """
    total = 0
    for i in range(2, 101, 2):
        total += i
    print(total)
    

    当然, 更为简单的办法是使用 Python 内置的sum函数求和,这样我们连循环结构都省掉了。

    """
    从1到100的偶数求和
    
    Version: 1.2
    Author: 骆昊
    """
    print(sum(range(2, 101, 2)))
    

    while循环

    如果要构造循环结构但是又不能确定循环重复的次数,我们推荐使用while循环。while循环通过布尔值或能产生布尔值的表达式来控制循环,当布尔值或表达式的值为True时,循环体(while语句下方保持相同缩进的代码块)中的语句就会被重复执行,当表达式的值为False时,结束循环。

    下面我们用while循环来实现从 1 到 100 的整数求和,代码如下所示。

    """
    从1到100的整数求和
    
    Version: 1.1
    Author: 骆昊
    """
    total = 0
    i = 1
    while i <= 100:
        total += i
        i += 1
    print(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的偶数求和
    
    Version: 1.3
    Author: 骆昊
    """
    total = 0
    i = 2
    while i <= 100:
        total += i
        i += 2
    print(total)
    

    break和continue

    如果把while循环的条件设置为True,即让条件恒成立会怎么样呢?我们看看下面的代码,还是使用while构造循环结构,计算 1 到 100 的偶数和。

    """
    从1到100的偶数求和
    
    Version: 1.4
    Author: 骆昊
    """
    total = 0
    i = 2
    while True:
        total += i
        i += 2
        if i > 100:
            break
    print(total) 
    

    上面的代码中使用while True构造了一个条件恒成立的循环,也就意味着如果不做特殊处理,循环是不会结束的,这就是我们常说的“死循环”。为了在i的值超过 100 后让循环停下来,我们使用了break关键字,它的作用是终止循环结构的执行。需要注意的是,break只能终止它所在的那个循环,这一点在使用嵌套循环结构时需要引起注意,后面我们会讲到什么是嵌套的循环结构。除了break之外,还有另一个在循环结构中可以使用的关键字continue,它可以用来放弃本次循环后续的代码直接让循环进入下一轮,代码如下所示。

    """
    从1到100的偶数求和
    
    Version: 1.5
    Author: 骆昊
    """
    total = 0
    for i in range(1, 101):
        if i % 2 != 0:
            continue
        total += i
    print(total)
    

    说明:上面的代码使用continue关键字跳过了i是奇数的情况,只有在i是偶数的前提下,才会执行到total += i。

    嵌套的循环结构

    和分支结构一样,循环结构也是可以嵌套的,也就是说在循环结构中还可以构造循环结构。下面的例子演示了如何通过嵌套的循环来输出一个乘法口诀表(九九表)。

    """
    打印乘法口诀表
    
    Version: 1.0
    Author: 骆昊
    """
    for i in range(1, 10):
        for j in range(1, i + 1):
            print(f'{i}×{j}={i * j}', end='\t')
        print()
    

    上面的代码中,for-in循环的循环体中又用到了for-in循环,外面的循环用来控制产生i行的输出,而里面的循环则用来控制在一行中输出j列。显然,里面的for-in循环的输出就是乘法口诀表中的一整行。所以在里面的循环完成时,我们用了一个print()来实现换行的效果,让下面的输出重新另起一行,最后的输出如下所示。

    1×1=1	
    2×1=2	2×2=4	
    3×1=3	3×2=6	3×3=9	
    4×1=4	4×2=8	4×3=12	4×4=16	
    5×1=5	5×2=10	5×3=15	5×4=20	5×5=25	
    6×1=6	6×2=12	6×3=18	6×4=24	6×5=30	6×6=36	
    7×1=7	7×2=14	7×3=21	7×4=28	7×5=35	7×6=42	7×7=49	
    8×1=8	8×2=16	8×3=24	8×4=32	8×5=40	8×6=48	8×7=56	8×8=64	
    9×1=9	9×2=18	9×3=27	9×4=36	9×5=45	9×6=54	9×7=63	9×8=72	9×9=81
    

    循环结构的应用

    例子1:判断素数

    要求:输入一个大于 1 的正整数,判断它是不是素数。

    提示:素数指的是只能被 1 和自身整除的大于 1 的整数。例如对于正整数 $\small{n}$,我们可以通过在 2 到 $\small{n - 1}$ 之间寻找有没有 $\small{n}$ 的因子,来判断它到底是不是一个素数。当然,循环不用从 2 开始到 $\small{n - 1}$ 结束,因为对于大于 1 的正整数,因子应该都是成对出现的,所以循环到 $\small{\sqrt{n}}$ 就可以结束了。

    """
    输入一个大于1的正整数判断它是不是素数
    
    Version: 1.0
    Author: 骆昊
    """
    num = int(input('请输入一个正整数: '))
    end = int(num ** 0.5)
    is_prime = True
    for i in range(2, end + 1):
        if num % i == 0:
            is_prime = False
            break
    if 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 的正整数,求两个数的最大公约数。

    提示:两个数的最大公约数是两个数的公共因子中最大的那个数。

    """
    输入两个正整数求它们的最大公约数
    
    Version: 1.0
    Author: 骆昊
    """
    x = int(input('x = '))
    y = int(input('y = '))
    for i in range(x, 0, -1):
        if x % i == 0 and 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次,这通常是难以接受的。我们可以使用欧几里得算法来找最大公约数,它能帮我们更快的得到想要的结果,代码如下所示。

    """
    输入两个正整数求它们的最大公约数
    
    Version: 1.1
    Author: 骆昊
    """
    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。

    例子3:猜数字游戏

    要求:计算机出一个 1 到 100 之间的随机数,玩家输入自己猜的数字,计算机给出对应的提示信息“大一点”、“小一点”或“猜对了”,如果玩家猜中了数字,计算机提示用户一共猜了多少次,游戏结束,否则游戏继续。

    """
    猜数字小游戏
    
    Version: 1.0
    Author: 骆昊
    """
    import random
    
    answer = random.randrange(1, 101)
    counter = 0
    while True:
        counter += 1
        num = int(input('请输入: '))
        if num < answer:
            print('大一点.')
        elif num > answer:
            print('小一点.')
        else:
            print('猜对了.')
            break
    print(f'你一共猜了{counter}次.')
    

    说明:上面的代码使用import random导入了 Python 标准库的random模块,该模块的randrange函数帮助我们生成了 1 到 100 范围的随机数。变量counter用来记录循环执行的次数,也就是用户一共猜了几次,每循环一次counter的值都会加 1。

    总结

    学会了 Python 中的分支结构和循环结构,我们就可以解决很多实际的问题了。通过这节课的学习,大家应该已经知道了可以用for和while关键字来构造循环结构。如果事先知道循环结构重复的次数,我们通常使用for循环;如果循环结构的重复次数不能确定,可以用while循环。此外,我们可以在循环结构中使用break终止循环,也可以在循环结构中使用continue关键字让循环结构直接进入下一轮次。

    ← 上一课05.分支结构下一课 →07.分支和循环结构实战