第六讲 循环结构

news2024/10/2 14:34:09

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

import time

print('hello, world')
time.sleep(1)
复制代码

说明:Python 内置time模块的sleep函数可以实现程序的休眠,参数1表示休眠的秒数,可以使用intfloat类型,例如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)可以构造出一个从03599的范围,当我们把这样一个范围放到for-in循环中,就可以通过前面的循环变量i依次取出从03599的整数,这就让for-in代码块中的语句可以重复3600次。当然,range的用法非常灵活,下面的清单给出了使用range函数的例子:

  • range(101):可以用来产生0100范围的整数,需要注意的是取不到101
  • range(1, 101):可以用来产生1100范围的整数,相当于是左闭右开的设定,即[1, 101)
  • range(1, 101, 2):可以用来产生1100的奇数,其中2是步长(跨度),即每次递增的值,101取不到。
  • range(100, 0, -2):可以用来产生1001的偶数,其中-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的整数求和,即∑n=1100n∑n=1100​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的值就会依次取到123、……,直到101。当i变成101时,while循环的条件不再成立,代码会离开while循环,此时我们输出变量total的值,它就是从1100求和的结果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,还是从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的整数。例如对于正整数n,我们可以通过在2n-1之间寻找有没有n的因子,来判断它到底是不是一个素数。当然,循环不用从2开始到n-1结束,因为对于大于1的正整数,因子应该都是成对出现的,所以循环到nn

​就可以结束了。

"""
输入一个大于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是一个素数;接下来,我们在2num ** 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循环的循环变量值是从大到小的,这样我们找到的能够同时整除xy的因子i,就是xy的最大公约数,此时我们用break终止循环。如果xy互质,那么循环会执行到i变成1,因为1是所有正整数的因子,此时xy的最大公约数就是1

用上面代码的找最大公约数在执行效率是有问题的。假如x的值是999999999998y的值是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:猜数字小游戏

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

"""
猜数字小游戏

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函数帮助我们生成了1100范围的随机数。变量counter用来记录循环执行的次数,也就是用户一共做出了几次猜测,每循环一次counter的值都会加1

总结

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/436938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Javaee spring jdbctemplate查询数据库,基于纯注解实现

为啥要用纯注解方式呢&#xff1f;因为xml中代码还是有点多&#xff0c;纯注解可以解决该问题 现在要做的很简单&#xff0c;就是用新建的SpringConfig这个类去替代xml 在测试类中加载核心配置类 SpringConfig类中 Configuratio Spring.xml配置类 ComponentScan <!--开…

Linux搭建Web服务器(三)——服务器编程基本框架以及事件处理模式

目录 0x01 服务器编程基本框架 0x02 两种高效的事件处理模式 Reactor 模式 Proactor 模式 模拟Proactor 模式 0x01 服务器编程基本框架 虽然服务器程序的种类繁多&#xff0c;但是其基本框架都是一样的&#xff0c;不同之处是在于处理逻辑。对于我们在这个服务器的搭建可以…

基于Jenkins实现Docker应用的持续集成与部署

先决条件 1. 服务器部署安装有docker 在docker应用开发中最常见的就是开发Dockerfile文件&#xff0c;可以使用代码仓库来管理它。 而在企业私有开发环境中是无法访问公有代码仓库&#xff08;如Github&#xff09;的。这时可以搭建私有代码仓库。 部署安装svn私有仓库 安…

GPT-4 验明真身的三个经典问题:快速区分 GPT-3.5 与 GPT-4

现在已经有很多 ChatGPT 的套壳网站&#xff0c;以下分享验明 GPT-4 真身的三个经典问题&#xff0c;帮助你快速区分套壳网站背后到底用的是 GPT-3.5 还是 GPT-4。 测试问题 1&#xff1a;What is tomorrow in relation to yesterday’s today&#xff1f;&#xff08;昨天的当…

《Shunted Transformer: Shunted Self-Attention》CVPR 2022 oral

论文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2022/papers/Ren_Shunted_Self-Attention_via_Multi-Scale_Token_Aggregation_CVPR_2022_paper.pdf 代码链接&#xff1a;https://github.com/OliverRensu/Shunted-Transformer​ 1. 动机 视觉转换器(ViT)模型…

vscode怎么对选定的代码格式化?ctrl+k,ctrl+f(格式化代码)

先选中代码&#xff1a; 然后按CTRL K 再按CTRLF 也可以先选择要格式化的代码块&#xff0c;ctrlshiftp&#xff0c;搜索format&#xff0c;然后第二个就是&#xff1a;

助你掌握搜索神器,10个实用的Elasticsearch查询技巧

前言 Elasticsearch是一个非常流行的搜索引擎&#xff0c;已经成为了许多企业的首选解决方案。然而&#xff0c;我们要想成为一个优秀的程序员&#xff0c;就必须掌握各种查询技巧。本文将向大家介绍10个实用的Elasticsearch查询技巧&#xff0c;并配上详细的代码示例&#xff…

Python基础实战1-简单介绍python

1 Python介绍 Python是一门优雅而健壮的编程语言&#xff0c;它继承了传统编程语言的强大性和通用性&#xff0c;同时也借鉴了脚本语言和解释语言的易用性。 1.1 Python的历史 Python是由创始人贵铎范罗萨姆&#xff08;Guido van Rossum&#xff09;在阿姆斯特丹于1989年圣…

在数字化质变“奇点”时刻,看数字生产力跃升的华为观

&#xff08;华为轮值董事长孟晚舟&#xff09; 进入2023年&#xff0c;以大语言模型为代表的新AI&#xff0c;打开了全球对于数字生产力的全新认知&#xff1a;高盛集团经济学家认为&#xff0c;ChatGPT等生成式AI最终可能在10年的时间里使得全球年GDP增长7%&#xff08;近7万…

pinia持久化存储方案——pinia-storage(自己写的,持续更新)

pinia持久化存储方案——pinia-storage pinia-storagepinia-storage Introduction版本更新说明(update introduction)安装(install)npm 安装&#xff08;npm install&#xff09; QuickStartcreate piniastore/indexstore/indexPinia.tsstore/indexPinia.js main.ts | main.jsA…

Direct3D 12——几何着色器——几何着色器概念

几何着色器 几何着色器这个可选阶段便位于顶点着色器与像素着色器之间。几何着色器所输出的图元由顶点列表定义而成。在退岀几何着色器时&#xff0c;必将顶点的位置变换到齐次 裁剪空间。换言之&#xff0c;经过几何着色器阶段的处理后&#xff0c;我们就得到了位于齐次裁剪空…

MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点3:EXPLAIN ANALYZE

文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点3&#xff1a;EXPLAIN ANALYZEEXPLAIN ANALYZE介绍EXPLAIN ANALYZE的特性EXPLAIN 和EXPLAIN ANALYZE的结果对比例题例题解析参考 MySQL 8.0 OCP (1Z0-908) 考点精析-性能优化考点3&#xff1a;EXPLAIN ANALYZE EXPLAIN…

部门来了个测试人,听说是00后,上来一顿操作给我看呆了...

今天上班开早会就是新人见面仪式&#xff0c;听说来了个很厉害的大佬&#xff0c;年纪还不大&#xff0c;是上家公司离职过来的&#xff0c;薪资已经达到中高等水平&#xff0c;很多人都好奇不已&#xff0c;能拿到这个薪资应该人不简单&#xff0c;果然&#xff0c;自我介绍的…

网络原理(TCP/UDP)

目录 一. 网络基础 1. IP地址 2. 端口号 3. 协议 4. OSI七层模型 二. UDP协议 2.1 UDP的协议端格式&#xff1a; 2.2 UDP的特点 三. TCP协议 3.1 TCP协议段格式 3.2 TCP原理 &#xff08;1&#xff09;确认应答机制 &#xff08;2&#xff09;超时重传机制 &#xff…

CmBacktrace库在工程中的添加和应用

CmBacktrace 介绍在工程中添加CmBacktrace断言打印全局变量的值循环输出错误信息串口处理看门狗处理 介绍 CmBacktrace下载 CmBacktrace &#xff08;Cortex Microcontroller Backtrace&#xff09;是一款针对 ARM Cortex-M 系列 MCU 的错误代码自动追踪、定位&#xff0c;错…

Javaee Spring template实现查询数据库表内容 基于半xml半注解

昨天用基于xml配置实现template查询数据库&#xff0c;今天基于半xml半注解方式实现,使用注解需要导入spring-aop-5.3.8.jar 导入jar包 项目结构&#xff1a; 其他代码在&#xff0c;先前上一篇文章已经给出 AccountServiceImpl package wwx.dao;import org.springframework…

定时器中断实验

实现内容 利用TIM3的定时器中断来控制DS1的翻转&#xff0c;在主函数用DS0 的翻转来提示程序正在运行。 定时器介绍 定时器可以认为是一个计数器&#xff1b;给定计数器一个初值&#xff0c;每当计数一次&#xff0c;就会走过一个固定的时间&#xff0c;当达到我们给定的初值…

强大的图像处理:ImageKit10.E ActiveX Crack

强大的图像处理&#xff01; ImageKit10 ActiveX 是一个组件&#xff0c;允许您快速轻松地向应用程序添加图像处理功能。使用 ImageKit10 ActiveX&#xff0c;您可以编写从 TWAIN 扫描仪和数码相机检索图像的应用程序;加载和保存图像文件并将图像从一种格式转换为另一种格式;编…

数字电路和模拟电路-半导体三极管

目录 1 什么是三极管&#xff1f; 1.1 放大状态时的偏执条件 1.1.1发射结加正向电压&#xff0c;扩散运动形成发射极电流IE 1.1.2扩散到基区的自由电子与空穴的复合运动形成基极电流IB 1.1.3集电结加反向电压&#xff0c;漂移运动形成集电极电流Ⅰc 2 三极管工作原理 2.…

5.图论(0x3f:从周赛中学算法 2022下)

来自0x3f【从周赛中学算法 - 2022 年周赛题目总结&#xff08;下篇&#xff09;】&#xff1a;https://leetcode.cn/circle/discuss/WR1MJP/ 周赛中的图论题目比较少&#xff0c;除了下面选的 DFS、BFS、拓扑排序、基环树、二分图判定等&#xff0c;还有最短路、DFS 时间戳等&a…