Skip to main content
 首页 » 编程设计

python之函数式编程 Python : smallest number divisible by each of the numbers 1 to 20

2025年05月04日22bluestorm

我想使用它的函数式编程功能在 python 中构建一个 while 循环,但直到现在我都失败了。

我所完成的是代码的和平,它应该计算可被 1 到 20 的每个数字整除的最小数字。但它似乎并没有大量使用函数式编程功能。并且还给我如下错误:

"RuntimeError: maximum recursion depth exceeded" at the line of the incrementation of "i";

即使这应该限制在 20 个。

def byYmult(x, y): return x % y == 0 
def first20div(): 
    i=0 
    for y in range(1,20): 
        i += byYmult(x, y) 
    return i >= 20 
 
def while_block(): 
    global x 
    if first20div():  
        print(x) 
        return 1 
    else: 
        x += 1 
    return 0 
 
x = 0 
while_FP = lambda: ((not first20div()) and while_block() ) or while_FP() 
while_FP()  

请您参考如下方法:

由于很多原因,这是非功能性的:

  1. 你不传递,也不返回函数;
  2. 您只在底部构造一个命名的 lambda 表达式,但这通常被认为是非 Pythonic;
  3. 通常函数式编程意味着你不改变数据,但在这里你定义了一个你更新的global x;
  4. 一些全局变量也被视为非功能性的:所有数据都应传递给函数。

所以有很多工作要做。此外,您描述的算法不是最优的。与其执行我们一直猜测数字直到最终幸运的蛮力方法,更好的方法是计算数字 1..20 的最小公倍数 (LCM)。

我们可以首先定义 - 以函数方式 - 我们可以通过首先计算最大公约数 (GCD) 来计算 LCM,这可以通过 Euclidean Algorithm 来完成.幸运的是,它已经在 math 包中:

from math import gcd 

现在LCM是:

def lcm(a,b): 
    return (a*b)//gcd(a,b) 

可以通过计算前两个数字的 LCM 来计算三个或更多数字的 LCM,然后将其作为第一个参数传递给具有第三个数字的 LCM,或者更正式地说:

lcm(x,y,z) == lcm(lcm(x,y),z) 

这可以通过使用 functools 中的 reduce 来完成:

from functools import reduce 
 
def lcm_multiple(xs): 
    return reduce(lcm, xs) 

现在我们可以通过传递一个 range(2,20) 对象来计算答案:

answer = lcm_multiple(range(2, 20)) 

或完整:

from math import gcd 
from functools import reduce 
 
def lcm(a,b): 
    return (a*b)//gcd(a,b) 
 
def lcm_multiple(xs): 
    return reduce(lcm, xs) 
 
answer = lcm_multiple(range(2, 20))