【问题标题】:map of function list and arguments: unpacking difficulty函数列表和参数的映射:解包难度
【发布时间】:2016-11-26 19:21:51
【问题描述】:

我在 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' object is not iterable
我以为我可以在reduce2中使用return reduce(l[0],l[1]),但仍然存在相同的错误。
我不明白这里 python 的行为。 如果我只使用return reduce(l),它会再次返回一个TypeError:reduce expected at least 2 arguments, got 1

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

【问题讨论】:

    标签: python dictionary zip reduce iterable-unpacking


    【解决方案1】:

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

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

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

    from operator import mul, add
    

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

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

    【讨论】:

    • 非常感谢您提供精确的命名约定。我没有意识到这一点。 add 做得很好,实际上 sum 与 reduce 是多余的,现在我明白了。
    【解决方案2】:

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

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

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

    但是,更好的是使用经常被忽略的variadic versionmap,而不是手动压缩参数:

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

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

    【讨论】:

    • 我知道starmap但没想到,另一方面,我不知道这个版本的地图。我希望你的回答得到更多的支持。我会接受 FMc 的回答,就像他先回答一样,但你的也值得称赞。
    猜你喜欢
    • 2011-11-16
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2010-12-19
    相关资源
    最近更新 更多