2016-11-26 33 views
2

我在一个mooc中必须编写一个函数,该函数返回输入列表的累积和,累积乘积,最大值和最小值。
这部分课程是关于函数式编程的,所以我想全力以赴,即使我可以使用其他方法。
所以,我想这一点:函数列表和参数的映射:开箱难度

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返回一个TypeError:int'对象不可迭代
我认为我可以在reduce2中使用return reduce(l [0],l [1]),但仍然有相同的错误。
我不明白python的行为。 如果我仅仅使用return reduce(l),它会再次返回一个TypeError:至少减少2个参数,得到1

这里发生了什么?我怎么能使它工作? 感谢您的帮助。

回答

3

实际上,你想这样的执行代码:

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

sum需要一个迭代,且无法通过reduce与直接使用真正兼容。相反,您需要一个带有2个参数并返回它们的和的函数 - 类似于mul的函数。你可以从operator

from operator import mul, add 

然后,只需在你的程序改变sumadd

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

+0

非常感谢关于命名约定的精确性。我没有意识到这一点。做得很好,实际上总和与减少是多余的,现在我明白了。 –

2

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

原因之一,而不是确定的reduce一个特殊版本,你可以使用itertools.starmap代替map,这是为这个目的而设计:

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

然而,更好的办法是使用了经常被忽视的mapvariadic version而不是手动压缩和解的参数:

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

它本质上是做zip + starmap给你。在功能编程方面,该版本的map类似于Haskell的zipWith函数。

+0

我知道starmap,但没有想到,另一方面,这个版本的地图对我来说是未知的。我希望你的回答能够得到更多答案。我会接受FMc的答案,因为他先回答了,但你的“值得赞美”。 –