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

时间:2016-11-26 19:21:51

标签: python dictionary zip reduce iterable-unpacking

我在一个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将产生4个元组(函数和参数列表l)所以我定义了reduce2因为这个原因,我想解压缩其中的zip但是它没用 Python返回一个TypeError:int'对象不可迭代
我认为我可以在reduce2中使用return reduce(l [0],l [1]),但仍然存在相同的错误。
我不明白python的行为。 如果我只使用return reduce(l),它会再次返回一个TypeError:减少预期的至少2个参数,得到1

这里发生了什么?我怎么能让它工作? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

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

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

sum采用可迭代的方式,并不能通过reduce直接使用。相反,您需要一个带有2个参数并返回其总和的函数 - 一个类似于mul的函数。您可以从operator

获取
from operator import mul, add

然后在您的计划中将sum更改为add

BTW,函数式编程有一个非常酷的变量命名约定:x用于一件事,xs用于列表。它比难以阅读的l变量名更好。它还使用单数/复数来告诉您是否正在处理标量值或集合。

答案 1 :(得分:1)

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

首先,您可以使用itertools.starmap代替专为此目的设计的reduce,而不是定义特殊版本的map

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

然而,更好的方法是使用经常被忽略的map def numbers(xs): return tuple(map(reduce, [add, mul, min, max], repeat(xs))) 而不是手动压缩参数:

zip

它基本上为你做starmap + map。在函数式编程方面,此版本的INSERT measurement sensor=[value1] 2016-11-26T00:00:00.00000000Z INSERT measurement sensor=[value2] 2016-11-26T00:00:00.00010000Z ... INSERT measurement sensor=[value10000] 2016-11-26T00:00:01.00000000Z 类似于Haskell的variadic version函数。