使用reduce和lambda表达式计算平方根和

-4 投票
2 回答
4085 浏览
提问于 2025-04-20 06:58

我最近在学习高阶函数,想写一个函数,它可以对一系列数字进行操作。具体来说,我想让它返回从0到100之间每隔一个的平方根的总和。

def sum(lower, upper, step = 1, func = lambda *x: x):
    return reduce(func, range(lower, upper + 1, step))

sum(0, 100, 2, math.sqrt)

TypeError: sqrt() takes exactly one argument (2 given)

如果有任何建议,我会很感激!

2 个回答

1

假设我们使用的是Python 3。我们先来写一个普通的代码:

result = 0
for i in range(0, 100, 2):
    result += math.sqrt(i)
print(result)

接下来,我们从这里开始,朝着你想要的方向走。首先,我们把 for 循环换成 mapsum

result = sum(map(math.sqrt, range(0, 100, 2)))
print(result)

现在,我们把这个放进一个函数里。

def sum_of_the_square_roots_from_0_to_100_with_step_2():
    return sum(map(math.sqrt, range(0, 100, 2)))
print(sum_of_the_square_roots_from_0_to_100_with_step_2())

接着,我们给这个函数添加一些参数。

def sum_of_func_from_0_to_100_with_step_2(func):
    return sum(map(func, range(0, 100, 2)))
print(sum_of_func_from_0_to_100_with_step_2)

然后,我们也给范围添加参数。

def sum_of_func_over_range(func, *range_args):
    return sum(map(func, range(*range_args)))
print(sum_of_func_over_range(math.sqrt, 0, 100, 2))

就这样!你可以传入任何一个函数(只要这个函数能接受至少一个参数)和一个范围的说明。

1

你似乎在假设 reduce 会在对每个元素应用 sort 后自动把列表中的元素加起来。也就是说,你可能认为 reduce 是这样工作的:

def reduce(func, lst, start):
    return sum(map(func, lst), start)

按照现在的写法,你需要给 sum 传递一个函数,这个函数不仅要对列表中的单个值应用 math.sqrt,还要把这个结果加到当前的总和上。

sum(0, 100, 2, lambda x, y: x + math.sqrt(y))

最简单的方法是使用我上面伪代码的主体:

def sum_of_sqroots(lower, upper, step=1, func=lambda x: x):
    return sum(map(func, range(lower, upper+1, step))

在功能性编程语言之外,reduce 很少被需要(在 Python 3 中,它被“降级”从内置命名空间移到了 functools 模块),因为通常写一个明确的循环来维护一个累加器会更清晰。

撰写回答