函数列表和参数的映射:解包难度

map of function list and arguments: unpacking difficulty

我在 mooc 中有一个作业,我必须在其中编写一个函数,该函数 return 是输入列表的累加和、累加积、最大值和最小值。
这部分课程是关于函数式编程的,所以我想全力以赴,即使我可以使用其他方法。
所以我尝试了这个:

from operator import mul
from itertools import repeat
from functools import reduce
def reduce2(l):
    print(l)
    return reduce(*l)
def numbers(l):
    return tuple(map(reduce2, zip([sum, mul,min, max], repeat(l,4))))
l=[1,2,3,4,5]
numbers(l)

我的问题是它不起作用。如果我在 map 中使用它,zip 将只传递一个要减少的对象,并且解压缩 zip 将产生(函数和参数列表 l)的 4 元组所以我为此定义了 reduce2,我想解压缩其中的 zip 但它没用。
Python return 类型错误:int' 对象不可迭代
我以为我可以在reduce2中使用return reduce(l[0],l[1]),但仍然有同样的错误。
我不明白 python 这里的行为。 如果我只使用 return reduce(l),它会再次 returns TypeError: reduce expected at least 2 arguments, got 1

这里发生了什么?我怎样才能让它发挥作用? 感谢您的帮助。

实际上,您正在尝试执行如下代码:

xs = [1, 2, 3, 4, 5]
reduce(sum, xs)

但是 sum 需要一个可迭代对象,并且与通过 reduce 直接使用并不兼容。相反,您需要一个函数,它接受 2 个参数和 returns 它们的总和——一个类似于 mul 的函数。你可以从 operator:

from operator import mul, add

然后只需在您的程序中将 sum 更改为 add

顺便说一句,函数式编程有一个非常酷的变量命名约定:x 代表一件事,xs 代表它们的列表。它比难以阅读的 l 变量名要好得多。它还使用 singular/plural 来告诉您是处理标量值还是集合。

正确诊断了代码中的错误。我只想为您的 map + zip 方法添加几个替代方案。

对于一个,而不是定义一个特殊版本的reduce,你可以使用itertools.starmap而不是map,这是专门为此目的设计的:

def numbers(xs): 
    return tuple(starmap(reduce, zip([add, mul, min, max], repeat(xs))))

然而,更好的方法是使用 map 中经常被忽略的 variadic version 而不是手动压缩参数:

def numbers(xs):
    return tuple(map(reduce, [add, mul, min, max], repeat(xs)))

它基本上为您完成了 zip + starmap。在函数式编程方面,此版本的 map 类似于 Haskell 的 zipWith 函数。