Python每日一练 10——for循环

news2024/12/30 3:41:11

Python每日一练 10——for循环

文章目录

  • Python每日一练 10——for循环
    • 一、for循环介绍
    • 二、实例一:等差数列前n项和
    • 三、实例二:计算阶乘
    • 四、实例三:拉马努金法计算圆周率
    • 五、实例四:百钱买百鸡

一、for循环介绍

for循环一般用于循环次数可确定的情况下,一般也被称为遍历循环

for 语句可以依据可迭代对象中的子项,按他们的顺序进行迭代。这些可迭代对象包括:range字符串列表集合字典文件对象等可迭代数据类型。

for循环基本结构如下:

for 循环变量  in 可迭代对象:
    语句块

需要注意,for开头的语句末尾一定是冒号结尾,其后面至少有一行语句需要在缩进的语句块中。缩进语句块中的语句重复执行多次,直到for语句遍历完可迭代对象。

程序执行时,从可迭代对象中逐一提取元素,赋值给循环变量,每提取一个元素执行一次语句块中的所有语句,总的执行次数由可迭代对象中元素(项)的个数确定。

二、实例一:等差数列前n项和

输入一下正整数,计算从1到这个正整数(包括该数本身)的所有整数的和。

range(1,n+1) 可生成1,2,……,n的序列,所以等差数列前n 项和的问题,可以用range实现:

算法描述:

  1. 先设置一个初值为0的变量
  2. 遍历由range()产生的整数序列,每得到一个整数就加到变量上
  3. 输出变量的值,即为所有整数的和
n = int(input())             # 将输入的字符转成整型,例如输入 100
sum_of_i = 0                 # 设累加容器初值为0
for i in range(1, n+1):      # 遍历1,2,...n的数列 
    sum_of_i = sum_of_i + i  # 将当前项加到累加容器上,注意此处要缩进,表示循环执行
print(sum_of_i)              # 输出累加总和,5050

运行的结果是:

100
5050

这个问题也可以直接用sum()函数结合range()函数来实现。将range()函数直接作为sum()函数的参数,可以直接获得range()函数所生成序列中全部元素的和。例如计算从1到n的加和可以写为以下程序:

n =  int(input())            # 将输入的字符转成整型,例如输入 100
print(sum(range(1, n + 1)))  # sum()函数可返回序列参数的元素的和,输出 5050

还可以简写成一段代码:

print(sum(range(1, int(input()) + 1)))  # sum()函数可返回序列参数的元素的和,输出 5050

改变range()函数中start、stop、step的值,便可以计算不同等差数列中连续n项和了,例如:

print(sum(range(1, 100, 2)))  # 100以内奇数的和2500
print(sum(range(0, 101, 2)))  # 不超过100的偶数的和2550
print(sum(range(0, 101, 5)))  # 不超过100的偶数5的整数倍的数的和1050
print(sum(range(50, 80, 5)))  # 序列50 55 60 65 70 75的和为375

运行的结果是:

2500
2550
1050
375

三、实例二:计算阶乘

一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1,自然数n的阶乘写作n!

range(1,n+1) 可生成1,2,……,n的序列,阶乘是数列前n 项积的问题,可以用range实现:

算法描述:

  1. 先设置一个初值为1的变量
  2. 遍历由range()产生的整数序列,每得到一个整数就乘到变量上
  3. 输出变量的值,即为所有整数的积,也就是阶乘值
n = int(input())           # 将输入的字符转成整型,例如输入6
fact = 1                   # 设阶乘初值为1,n为0时不进入循环,0的阶乘为1
for i in range(1, n + 1):  # 遍历1,2,...n的数列
    fact = fact * i        # 将当前项加到累加容器上
print(fact)                # 输出累加总和,720

运行的结果是:

6
720

math库中有一个用于计算阶乘的函数factorial(n),可以调用函数简化程序设计。

import math
print(math.factorial(6))    # factorial() 为计算阶乘的函数

结果跟上面的一样。

四、实例三:拉马努金法计算圆周率

之前我们学习过的Leibniz公式计算圆周率的方法存在收敛慢的问题。拉马努金曾经提出过很多收敛速度极快的求π的公式,‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬比如这个拉马努金在1914年发布的以他自己名字命名的著名公式可用于计算圆周率:

在这里插入图片描述

公式中的希腊字母∑,英文译音是Sigma, 表示数学中的求和号,主要用于求多项数之和,公式展开可以表示为k从0到n时各项的累加,可以用循环实现。这个公式收敛速度极快,累加3次时,就可以达到math.pi相同的精度。

from math import factorial  # 导入math库中的factorial函数

n = int(input())    # 输入正整数表示累加项数
result = 0          # 累加初值为0
for k in range(n):  # 重复执行n次累加
    result = result + 2 * 2 ** 0.5 / 9801 * factorial(4 * k) * (1103 + 26390 * k) / (factorial(k) ** 4 * 396 ** (4 * k))
pi = 1 / result     # 累加结果取倒数为圆周率值
print(pi)           # 输出圆周率值

运行的结果是:

3
3.141592653589793

for循环可以多重嵌套使用,每增加一层循环多一层缩进,最内层循环体内的语句执行的次数为各重循环次数相乘。如果循环语句的循环体中又出现循环语句,就构成多重循环结构。for和while都支持多重循环,且可以混用。一般常用的有二重循环和三重循环。循环层数越多,运行时间越长,程序越复杂,最内层程序语句执行的次数是各层循环次数的乘积

五、实例四:百钱买百鸡

我国古代数学家张丘建在《算经》一书中提出的“百钱买百鸡”的数学问题,题目意思是1只公鸡5文钱、1只母鸡3文钱、3只小鸡1文钱。计算并输出有几组可能的解?

在这里插入图片描述

若用数学方法求解,3个未知量,只能列2个方程,不能直接求解。

在计算机领域,这个问题可以用枚举算法求解,枚举算法的思想是:将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,保留合适的,舍弃不合适的。

基本思路如下:

(1)确定枚举对象、范围和判定条件。

(2)逐一枚举可能的解并验证每个解是否是问题的解。

算法步骤:

(1)确定解题的可能范围,不能遗漏任何一个真正解,同时避免重复。

(2)判定是否是真正解的方法。

(3)为了提高解决问题的效率,使可能解的范围将至最小

我们先用一个规模较小的问题为例。日常用的皮箱的经常是三位的密码锁,当忘记密码时,可以采用逐位猜测的方法试出来密码,我们知道,3个数字的全部组合只有1000个,所以我们试1000次一定可以找到密码。

具体操作方法:

  • 1.先固定第1位为0

    • b. 第2位设0
      • ⅰ. 第3位从0试到9
    • c. 重复b并依次设1-9
  • 2.重复1并依次设第1位为1-9

    算法:
    1.第1位数遍历从0到9的数字
    2.第2位数遍历从0到9的数字
    3.第3位数遍历从0到9的数字
    4.比较当前的三位数是否与密码相同,若相同
    5.输出当前三位数

import random  # 导入随机数模块

keys = random.randint(100, 999)  # 随机产生一个三位整数
print(keys)  # 查看当前生成的随机数,每次结果不同

for i in range(10):          # 猜测百位上的数字
    for j in range(10):      # 猜测十位上的数字
        for k in range(10):  # 猜测个位上的数字
            # 三个数字拼接为一个三位整数,若此三位数与随机产生的相同,则找到密码
            if i * 100 + j * 10 + k == keys:  
                print(f'密码是{i}{j}{k}')     

运行的结果是:

947
密码是947

参考找回密码的程序,将问题规模扩大,遍历公鸡、母鸡和小鸡的数量都从1到100,一定可以找到所有正确的解。

for cock in range(1, 101):              # 公鸡数量不为0且小于或等于100
    for hen in range(1, 101):           # 母鸡数量不为0且小于或等于100
        for chicken in range(1, 101):   # 小鸡数量大于0小于等于100且是3的倍数
            # 鸡的总数为100,钱的总数为100
            if cock + hen + chicken == 100 and 5 * cock + 3 * hen + chicken // 3 == 100 and chicken % 3 ==0 :
                print(f'公鸡{cock}只,母鸡{hen}只,小鸡{chicken}只')

运行的结果是:

公鸡4只,母鸡18只,小鸡78只
公鸡8只,母鸡11只,小鸡81只
公鸡12只,母鸡4只,小鸡84

这是一个三重循环,最内层循环中的if语句的执行次数约为:100 * 100 * 100 = 100万次,这是一个很大的数字,计算时间开销也很大,算法的效率不高。我们可以用“剪枝”这个方法,剪枝的思想就是剪掉不可能出现的情况,避免计算机多余的运算

我们可以用range(3, 101, 3)产生3的整数倍的数列,小鸡数量是3的倍数,所以可取的值一定在这个数列中。

for cock in range(1, 101):                 # 公鸡数量不为0且小于或等于100
    for hen in range(1, 101):              # 母鸡数量不为0且小于或等于100
        for chicken in range(3, 101, 3):   # 小鸡数量大于0小于等于100且是3的倍数
            # 鸡的总数为100,钱的总数为100
            if cock + hen + chicken == 100 and 5 * cock + 3 * hen + chicken // 3 == 100:
                print(f'公鸡{cock}只,母鸡{hen}只,小鸡{chicken}只')

以上程序执行次数约为:100 * 100 * 33 = 33万次,相比之前减少了,但数字仍然很大。

实际上当公鸡和母鸡数量x, y 确定的情况下,小鸡的数量 z 可由100 – x - y计算,并不需要用循环进行遍历,可将其用两重循环实现求解。

for cock in range(1, 101):          # 公鸡数量不为0且小于或等于100
    for hen in range(1, 101):       # 母鸡数量不为0且小于或等于100
        chicken = 100 - cock - hen  # 小鸡数量可由公鸡和母鸡数量计算得到
        if chicken % 3 == 0 and 5 * cock + 3 * hen + chicken // 3 == 100:
            print(f'公鸡{cock}只,母鸡{hen}只,小鸡{chicken}只')

以上程序执行次数约为:100 * 100 = 1万次,效率提高了33倍,我们还可以继续减少执行次数。

由于要求每种鸡数量都不能为0,所以公鸡最多只能买19只,母鸡最多只能买32只,这样继续裁剪,减少外面两层循环的次数:

for cock in range(1, 20):           # 公鸡数量不超过20
    for hen in range(1, 33):        # 母鸡数量不超过33
        chicken = 100 - cock - hen  # 小鸡数量可由公鸡和母鸡数量计算得到
        if chicken % 3 == 0 and 5 * cock + 3 * hen + chicken // 3 == 100:
            print(f'公鸡{cock}只,母鸡{hen}只,小鸡{chicken}只')

以上程序执行次数约为:19 * 32 = 608次,相比之前的几次次数减少了很多很多。

从结果中可以发现这样的一个规律:

公鸡是4的倍数,母鸡是7的递减率,小鸡是3的递增率,为了确认这一规律,数学上推导一下这个不定方程:

x + y + z = 100

5x + 3y + z/3 = 100

消去z可得:7x + 4y = 100

由此可得:

y = 25 - (7/4)x

z = 75 + (3/4)x

因为0 < y < 100,且是自然数,则可得知 x 必为4的整数倍的正整数才能保证y 和 z 都是整数,x 最大值必小于16 才能保证y 值为正数,所以x值只能取4、8、12,这样只循环3次就可以找到所有可能的解,所有我们可以继续优化代码提高效率:

for cock in range(4, 16, 4):    # cock 初值为4,小于16,步长为4
    hen = 25 - cock // 4 * 7    # 整除“//”符号保证运算结果仍为整数
    chicken = 75 + cock // 4 * 3
    print(f'公鸡{cock}只,母鸡{hen}只,小鸡{chicken}只')

尽可能减少循环嵌套的层数,让代码趋于扁平,使逻辑更简单,更容易阅读、理解和维护代码。需多重循环求解时,可以将内层循环的功能定义成函数,将二重循环转换为两个一重循环,使代码逻辑更清晰。

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

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

相关文章

前端_Vue_9.模板引用、组件基础

文章目录一、模板引用1.1. 访问模板引用1.2. v-for 中的模板引用1.3. 函数模板引用1.4. 组件上的 ref1.5. 小结二、组件基础 ⭐2.1. 定义一个组件2.2. 使用组件2.3. 传递props2.4. 监听事件2.5. 通过插槽&#xff08;slot&#xff09;来分配内容2.6. 动态组件2.7. DOM模板解析注…

go 库 Cobra 现代化的命令行框架

go 库 Cobra 现代化的命令行框架 文章目录go 库 Cobra 现代化的命令行框架1. 简介2. 主要功能3. 应用举例4. Cobra 安装5. 使用 Cobra 库创建命令5.1 创建 rootCmd5.2 创建 main.go5.3 添加命令5.4 编译并运行6. 特性6.1 使用标志6.2 非选项参数验证6.3 PreRun and PostRun Hoo…

手绘图说电子元器件-电声转换器件

电声转换器件包括能够将电信号转换为声音的扬声器、耳机、讯响器和蜂鸣器,能够将声音转换为电信号的传声器,能够进行电磁转换的磁头和具有压电效应的晶体等。 扬声器 扬声器俗称喇叭,是一种常用的电声转换器件,其基本作用是将电信号转换为声音,在收音机、录音机、电视机…

Linux | 套接字(socket)编程 | TCP协议讲解 | 通信模型搭建

文章目录TCP模型的特性TCP接口介绍TCP服务器套接字设置TCP客户端套接字设置TCP模型的特性 TCP是属于传输层协议的一种&#xff0c;上篇博客介绍了另一种传输层协议——UDP&#xff0c;关于它们之间的区别&#xff0c;这里再提一下 TCPUDP传输层协议传输层协议有连接无连接可靠…

Word控件Spire.Doc 【评论】教程(3):在C#、VB.NET中从Word文档中提取注释并保存在TXT文件中

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

[Leetcode] 合并两个有序数组、链表

1.合并两个有序数组 原地合并数组&#xff0c;即不使用额外的空间 --> 使用三个指针&#xff0c;从尾部往前处理 题目链接&#xff1a;https://leetcode.cn/problems/merge-sorted-array/ nums1 总长度 mn&#xff0c;自身长度m&#xff1b;nums2 自身长度n&#xff0c; 使…

SSRF渗透与攻防(一)

目录 前言 SSRF是什么 危害&#xff08;利用方式): SSRF漏洞原理&#xff1a; CURL协议&#xff1a; SSRF常见场景 社会化分享功能&#xff1a; 如何发现SSRF漏洞 工具利用&#xff1a; 如何防御SSRF漏洞 前言 SSRF(Server-Side Request Forgery:服务器端请求伪造) 是…

rocketmq 实战问题汇总

rocketmq 实战过程会遇到这样或者那样的问题&#xff0c;今天我们专门抽出一篇文章来分析一下汇总一下&#xff0c;避免以后踩同样的坑&#xff1a; 1、找不到JDK的问题&#xff1a; 综合分析&#xff0c;是因为JDK安装的目录有空格导致的&#xff1a;Program Files 两个单词之…

电子招标采购系统源码—企业战略布局下的采购寻源

​ 智慧寻源 多策略、多场景寻源&#xff0c;多种看板让寻源过程全程可监控&#xff0c;根据不同采购场景&#xff0c;采取不同寻源策略&#xff0c; 实现采购寻源线上化管控&#xff1b;同时支持公域和私域寻源。 询价比价 全程线上询比价&#xff0c;信息公开透明&#xff0…

CANoe—基于DoIP通过CAPL实现与ECU通信测试

如下连接是在CANoe中基于DoIP通过加载诊断数据库实现CANoe与待测ECU诊断通信: CANoe链接 本文继续此话题,通过一个简单的CAPL Demo,实现CANoe与ECU进行DoIP通信。 首先在CANoe新建Ethernet工程: 在CANoe “Simulation Setup”中新建CAPL Test Module: 在此例中采用CANo…

DHCP原理和实验

目录 DHCP基本认识和原理 场景一、同网段DHCP 场景二、不同段DHCP&#xff08;中继DHCP&#xff09; DHCP基本认识和原理 DHCP&#xff08;Dynamic Host Configuration Protocol动态主机协议&#xff09;。 作用&#xff1a;为局域网络中主机动态分发地址&#xff0c;以及…

C#里使用ExcelDataReader读取EXCEL文件的简单方法

C#里使用ExcelDataReader读取EXCEL文件的简单方法 读取EXCEL文件是比较常见的需求,所以在C#里也会经常遇到。 比如客户需要保存的条码数据,他们可以使用EXCEL来扫码进去,并且进行修改和核验, 然后软件就需要读取这些EXCEL文件,并且从这里得到所需要的条码。 要从EXCEL里…

Android 查看隐私权限方法调用者集合

背景 辛辛苦苦迭代完当前版本&#xff0c;准备推送 App 到应用市场上架&#xff0c;却收到拒审通知&#xff1a;App隐私合规上架护航版检测报告&#xff0c; 报告内容&#xff1a; 场景2:APP以隐私政策弹窗的形式向用户明示收集使用规则&#xff0c;未经用户同意&#xff0c;…

页面崩溃了!记录一次测试中出现的前端内存溢出现象

前情回顾 前几天在一次web应用测试过程中&#xff0c;前端发起了向后端接口的查询请求&#xff0c;由于后端响应较慢&#xff0c;前端一直处于等待响应返回状态。在几分钟后&#xff0c;突然页面出现让人惊悚的“噢噢&#xff0c;页面崩溃了”几个大字。 看到这几个字的一瞬间…

基于GitLab构建企业级CICD-Gitlab-Runner

背景 在过往企业开发中&#xff0c;大部分企业从开发到测试&#xff0c;到部署目前还是手工进行在一些某些中大型企业中&#xff0c;目前构建及部署还是直接使用二进制包部署&#xff0c;或直接单机运行在某些场合下&#xff0c;仓库中代码的编译需要硬件支持&#xff0c;致使…

SSM框架学习记录-Maven_day01

1.分模块开发 将原始模块按照功能拆分成若干个子模块&#xff0c;方便模块间的相互调用&#xff0c;接口共享&#xff1a;比如有订单和商品两个模块&#xff0c;它们都需要使用到商品的模型类&#xff0c;如果在这两个模块中都写模型类&#xff0c;就会出现重复代码&#xff0c…

Doris部分列更新在广告行业应用

背景&#xff1a;业务需要在不同的时间点对同一个session_id上的广告行为&#xff08;展示、点击、转换等&#xff09;数据的更新。 基于HBase归因 更新原理&#xff1a;以session_id为Key在HBase中写入数据&#xff0c;数据更新是先点查到历史数据&#xff0c;补齐当前数据后…

风已起,待云涌---多维度理解云安全

Fix the Unknown,Before You Know it. 新时代大门开启的时候&#xff0c;蜂拥而上的大都是勇士&#xff0c;风已起&#xff0c;待云涌&#xff01; 1.云安全&#xff1a; 未来安全的能力将成为计算、存储、网络之外的第四大基础设施&#xff0c;并全部融入到云基础设施中&…

Python爬虫入门 ~ selenium访问元素信息与交互基本使用

访问元素信息 前面我们成功定位到了页面的标签元素&#xff0c;那接下来就该轮到获取元素的信息了&#xff0c;常用的函数有以下几种: get_attributetexttag_name 前置准备 from selenium import webdriver from selenium.webdriver.chrome.service import Service from sel…

【Django项目开发】用户认证功能开发(四)

一、JWT Token配置 1、下载djangorestframework-jwt pip install djangorestframework-jwt2、settings.py指定使用的认证类JSONWebTokenAuthentication REST_FRAMEWORK {# 指定使用的认证类# a、在全局指定默认的认证类&#xff08;认证方式&#xff09;DEFAULT_AUTHENTICA…