首页 > 编程语言 >Python程序笔记20230305

Python程序笔记20230305

时间:2023-04-13 13:55:38浏览次数:46  
标签:product 20230305 Python reduce 笔记 divisible range print 函数

n 以内能被 m 整除的数的和、积

最初版本

计算指定数字内所有偶数的和

n = int(input("请输入指定的n:"))  
i = 0  
mysum = 0  
  
while i <= n:  
	if i % 2 == 0:  
		mysum = mysum + i  
i = i + 1  
  
print(f"{n}以内的所有偶数的和是{mysum}")  
print("{0}以内的所有偶数的和是{1}".format(n, mysum))

对于两行输出代码:
第一行代码使用了 f-string,语法形式为在字符串前加上字母 f,然后使用花括号 {} 括起来的变量名或表达式,就可以在字符串中插入变量的值。在这个例子中,f-string 会将变量 n 和 mysum 的值插入到字符串中。
第二行代码使用了字符串的 format() 方法,它可以用来替换字符串中的占位符。在这个例子中,字符串中的占位符是 {0} 和 {1},分别对应 format() 方法的第一个参数和第二个参数。在 format() 方法中,可以按照顺序传递参数值,或者使用关键字参数来指定参数的位置。输出结果与 f-string 相同

优化方法

使用 for 循环

n = int(input("请输入指定的n"))
mysum = 0

for i in range(0, n+1, 2):
    mysum += i

print(f"{n}以内的所有偶数的和是{mysum}")

使用列表推导式

n = int(input("请输入指定的n:"))
mysum = sum([i for i in range(n+1) if i % 2 == 0])
print(f"{n}以内的所有偶数的和是{mysum}")

使用内置 math 模块

import math
n = int(input("请输入指定的n:"))
mysum = math.ceil(n/2) * (n//2 + 1)
print(f"{n}以内的所有偶数的和是{mysum}")

使用 math.ceil() 函数来将 n 除以 2 并向上取整。这里使用向上取整的原因是为了确保当 n 为奇数时,也能够正确计算偶数和。例如,当 n 为 5 时,5//2 = 22*3 = 6,这样就能正确计算 5 以内的偶数和了。
使用整除运算符 // 和取模运算符 % 来计算 n 的一半和 n 的下取整值,然后将它们相乘得到所有偶数的和。这个计算公式的思路是:偶数和 = 2 + 4 + 6 + ... + n(n 为偶数)= 2 * (1 + 2 + 3 + ... + n/2) = 2 * [n/2 * (n/2 + 1)/2] = n/2 * (n/2 + 1),其中 [ ] 表示向下取整。注意,当 n 为奇数时,n//2 会向下取整,因此会忽略掉最后一个奇数,但这并不影响结果,因为最后一个奇数一定不是偶数。

使用 peephole 优化技术

n = int(input("请输入指定的n:"))
i = 0
mysum = 0

while i <= n:
    if not i & 1: # 使用位运算代替求余运算
        mysum += i # 使用增量赋值代替普通赋值
    i += 1

print(f"{n}以内的所有偶数的和是{mysum}")

在 Python 中,位运算比求余运算更快,因此可以提高代码的执行效率。在这个例子中,使用了位运算 & 来判断 i 是否为偶数。由于偶数的二进制表示的最后一位为 0,因此 i & 1 的结果为 0 就意味着 i 是偶数。这样就避免了使用 % 操作符来求余数,提高了代码的性能。
使用了增量赋值 += 代替普通赋值。增量赋值可以将两个操作合并成一个,从而提高代码的执行效率。
这些优化方法可能对于小规模的数据集并没有太大的作用,但是在处理大规模数据集时,它们能够提高代码的执行效率,从而减少程序的运行时间和资源消耗。

关于位运算

当我们将一个二进制数和 1 进行按位与(&)操作时,只有最后一位是 1 的二进制数和 1 进行按位与操作的结果是 1,其余情况下结果都是 0。
如果一个数是偶数,它的二进制表示的最后一位是 0,那么它和 1 进行按位与操作的结果也是 0;
如果一个数是奇数,它的二进制表示的最后一位是 1,那么它和 1 进行按位与操作的结果就是 1。
需要注意的是,在进行位运算时,应该使用位运算符 &|^~,而不是逻辑运算符 andornot。因为位运算符是针对二进制数的,它们操作的是二进制数的每一位,而逻辑运算符是针对布尔值的,它们操作的是 True 和 False。

进阶版本 1

n = int(input("请输入指定的n:"))
m = int(input("请输入指定的m:"))

sum_divisible_by_m = sum([i for i in range(m, n+1) if i % m == 0])
product_divisible_by_m = 1
for i in range(m, n+1):
    if i % m == 0:
        product_divisible_by_m *= i

print(f"{n}以内能被{m}整除的数的和是{sum_divisible_by_m}")
print(f"{n}以内能被{m}整除的数的积是{product_divisible_by_m}")

这段代码首先通过 input() 函数获取用户输入的 n 和 m,然后分别使用 sum() 函数和 for 循环来计算小于等于 n 且能被 m 整除的数的和和积。
需要注意的是,第 4 行代码中的列表推导式中的 range() 函数使用了起始值 m,这是为了确保生成的列表中的第一个元素是能被 m 整除的数。同时,第 5 行代码中的 for 循环也从 m 开始遍历,这是为了避免重复计算 m。如果不从 m 开始遍历,那么 m 就会被计算两次,一次在列表推导式中,一次在 for 循环中。
在 Python 中没有内置的连乘函数,但可以通过使用内置函数 reduce() 或者 NumPy 库中的 prod() 函数来实现连乘。

reduce() 函数

reduce() 函数位于 functools 模块中,它可以对一个序列中的元素进行累积计算。

from functools import reduce

product = reduce(lambda x, y: x * y, [1, 2, 3, 4, 5])
print(product)  # 输出 120

使用 reduce() 函数将列表 [1, 2, 3, 4, 5] 中的所有元素累乘起来。reduce() 函数接受两个参数:一个函数和一个序列。函数用于对序列中的元素进行累积计算,序列是要计算的元素。在这个例子中,我们使用 lambda 表达式定义了一个匿名函数来计算累乘结果,然后将这个函数和列表 [1, 2, 3, 4, 5] 传递给 reduce() 函数。

prod() 函数

如果需要对 NumPy 数组进行连乘计算,可以使用 NumPy 库中的 prod() 函数。

import numpy as np

product = np.prod([1, 2, 3, 4, 5])
print(product)  # 输出 120

修改后的结果

from functools import reduce

n = int(input("请输入指定的n:"))
m = int(input("请输入指定的m:"))

sum_divisible_by_m = sum([i for i in range(m, n+1, m)])
product_divisible_by_m = reduce(lambda x, y: x * y, range(m, n+1, m), 1)

print(f"{n}以内能被{m}整除的数的和是{sum_divisible_by_m}")
print(f"{n}以内能被{m}整除的数的积是{product_divisible_by_m}")

  • lambda是一种创建匿名函数的方式,它可以让你在一行代码中定义一个简单的函数,而不需要使用def关键字。lambda函数的语法是lambda 参数: 表达式,它表示一个接受参数并返回表达式计算结果的函数。例如,lambda x, y: x * y就是一个接受两个参数x和y,并返回它们相乘结果的函数。
  • reduce是一个内置函数,它可以对一个可迭代对象(如列表)中的元素进行累积操作,从而得到一个单一的值。reduce函数的语法是reduce(函数, 可迭代对象, 初始值),它表示从左到右依次将可迭代对象中的元素和初始值作为参数传递给函数,并将函数的返回值作为下一次调用的初始值,直到可迭代对象中的元素遍历完毕。例如,reduce(lambda x, y: x + y, [1, 2, 3, 4], 0)就是对列表[1, 2, 3, 4]中的元素进行求和操作,并以0作为初始值,最终得到10。

代码reduce(lambda x, y: x * y, range(m, n + 1, m), 1)是什么意思呢?

  • range(m, n + 1, m)是一个生成器,它可以产生从m到n(包含n)之间以m为步长的整数序列。
  • lambda x, y: x * y是一个接受两个参数x和y,并返回它们相乘结果的函数。
  • reduce(lambda x, y: x * y, range(m, n + 1, m), 1)就是对range(m, n + 1, m)中的元素进行累乘操作,并以1作为初始值。例如,如果m=2,n=10,那么这个表达式就相当于计算(1 * 2 * 4 * 6 * 8 * 10),最终得到3840。

需要注意的是,代码中的 range() 函数使用了步长 m,这是为了确保生成的序列中的所有元素都能被 m 整除。同时,第 5 行代码中的列表推导式中的 range() 函数也使用了步长 m,这是为了避免重复计算。如果不使用步长 m,那么就会生成一个包含所有小于等于 n 的数的列表,然后再筛选出能被 m 整除的数,这样就会浪费一些时间和空间。

进阶版本 2

import numpy as np
from functools import reduce

# 输入检查:确保 n 和 m 都是正整数
while True:
    try:
        n = int(input("请输入指定的 n:"))
        m = int(input("请输入指定的 m:"))
        if n > 0 and m > 0:
            break
        else:
            print("n 和 m 必须是正整数,请重新输入")
    except ValueError:
        print("n 和 m 必须是正整数,请重新输入")

# 如果 n 太大,就使用 1000000 代替
if n > 1000000:
    n = 1000000
    print("n 太大,已经自动调整为 1000000")

# 计算能被 m 整除的数的和和积
sum_divisible_by_m = sum([i for i in range(m, n+1, m)])
product_divisible_by_m = reduce(lambda x, y: x * y, range(m, n+1, m), 1)
product_divisible_by_m1 = np.prod(range(m, n+1, m))

# 输出结果
print(f"{n} 以内能被 {m} 整除的数的和是 {sum_divisible_by_m}")
print(f"{n} 以内能被 {m} 整除的数的积是 {product_divisible_by_m}")
print(f"{n} 以内能被 {m} 整除的数的积是 {product_divisible_by_m1}")

标签:product,20230305,Python,reduce,笔记,divisible,range,print,函数
From: https://www.cnblogs.com/taurusxw/p/17314526.html

相关文章

  • python-zip
    python-zipzip()是Python的一个内建函数定义:zip([iterable,...])zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list(列表)。若传入参数的长度不等,则返回list的长度和参数中长度最短的对......
  • 笨办法学 Python · 续 练习 3:质量
    练习3:质量原文:Exercise3:OnQuality译者:飞龙协议:CCBY-NC-SA4.0自豪地采用谷歌翻译我将提出一个关于认知的科学理论,我并不能证明它:你所做事情的记忆,会让你思考最终产品,这是正确的行为。这基于我所做的,几乎每一个创造性的事情的观察,它是这样:你创造的东西需要很长一段时间。这可......
  • 笨办法学 Python · 续 练习 9:`sed`
    练习9:sed原文:Exercise9:sed译者:飞龙协议:CCBY-NC-SA4.0自豪地采用谷歌翻译使用这些小型项目来研究你自己是有用的,但让我们来看看你主要关注的主题:开始工作的启动流程,例如你的文本编辑器,你可以打字打的多好,以及计算机内部发生的其他事情。心理状态,当你开始工作时,建议将日志作为......
  • 笨办法学 Python · 续 练习 7:`grep`
    练习7:grep原文:Exercise7:grep译者:飞龙协议:CCBY-NC-SA4.0自豪地采用谷歌翻译find命令在45分钟内应该可能是一个挑战,但它是一个很好的挑战。到了这个时间,你应该可以去掉尽可能多的,阻止你开始的障碍。你可能会发现,当你清除一些障碍时,你的技能会变得更糟。例如,我以前在开始工作......
  • 笨办法学 Python · 续 练习 8:`cut`
    练习8:cut原文:Exercise8:cut译者:飞龙协议:CCBY-NC-SA4.0自豪地采用谷歌翻译希望你正在深入学习Python,甚至了解你自己和你的工作方式。在本书的这一部分,通过学习如何优化你的流程,你学到了流程和创造力的一些事情。的确,有阻碍的情况下你不能发挥创造力,但是你应该意识到,改善自己......
  • 笨办法学 Python · 续 练习 4:处理命令行参数
    练习4:处理命令行参数原文:Exercise4:DealingwithCommandLineArguments译者:飞龙协议:CCBY-NC-SA4.0自豪地采用谷歌翻译在你能处理本书的第一部分之前,你需要完成一些简单的黑魔法,教你如何使用Python中的命令行参数。传统上我们称这种黑魔法为“spike”。该术语来自于一个小......
  • 笨办法学 Python · 续 练习 11:`uniq`
    练习11:uniq原文:Exercise11:uniq译者:飞龙协议:CCBY-NC-SA4.0自豪地采用谷歌翻译在最后两个练习的开始,没有什么可说的了。你应该知道如何思考你的工作环境,你如何开始,你如何坐下来,影响你开始的任何事情。你也应该使用这些小小的45分钟的项目,突破了起始状态。如果你还没有弄清楚......
  • 关于免费笔记软件和免费同步,长文,保存观看
    前言这段可以略过最早使用的笔记软件(应该说是网页摘录软件)是网文快捕CyberArticle,但不停换电脑后当年保存的资料基本都遗失了,那可是我翻阅众多涩涩网站的精华文章。后来网文快捕推出了在线笔记软件“为知笔记”,经历了为知笔记收费、被收购、大升级,分享需审核等一系列改变,虽然......
  • 学习笔记399—彻底明白ip地址,区分localhost、127.0.0.1和0.0.0.0
    彻底明白ip地址,区分localhost、127.0.0.1和0.0.0.0通俗的了解IP地址是什么对于IP地址,大家并不陌生,特别是在网络访问中我们会经常使用到(平时对域名如百度的www.baidu.com的访问,本质就是对域名所绑定的IP地址的访问),那么IP地址是什么呢?首先,我们要知道网络中的相互访问其实就是在......
  • CS231N assignment 2 _ normalization 学习笔记 & 解析
    预警:本次内容不算多,但数学推导较复杂Normalization归一化的意义之前内部的权重没有做过标准化.实际上如果能标准化,可以提升训练效果,甚至可以提升精度(虽然不大).设立专门的batch/layernormalization层的意义在于:梯度更加规范对于学习率(可以更高),初始化权重等......