【问题标题】:Using reduce to iterate over list of functions and call each one使用 reduce 迭代函数列表并调用每个函数
【发布时间】:2017-06-29 06:22:53
【问题描述】:

目前我正在使用带有函数名称的字符串列表来修复我的软件流程:

flow = [
  "func1",
  "func2",
  "func3",
  "func4",
  "func5"
]

然后我遍历流程并调用每个传递选项的流程:

options = {}
[getattr(__import__(phase), phase)(options) for phase in flow]

我想知道是否可以做同样的事情,但避免副作用,使用 reduce。目前,这种方法使函数接收选项,但没有必要为下一个函数返回选项,所以我正在更改在其他范围内声明的选项。

谢谢。

【问题讨论】:

  • 你是如何建立这个列表的?你能把函数对象放在那个列表中吗[func1, func2, ...] 这样会更简单
  • 为什么会简单很多?我只会删除 get 和 import 属性。
  • for 循环会产生副作用,我想使用最后一个函数的返回码结束软件。我的意思是,如果软件成功,最后一个函数会返回0,表示一切正常
  • 所有函数都接收输入,前一个函数的输出调用
  • 对不起,您理解的副作用在哪里?

标签: python functional-programming reduce


【解决方案1】:

您可以使用functools.reduce(在其他函数式编程语言如 Haskell 中有时称为fold)来调用函数。

然而,在这种情况下,您需要定义一个函数采用两个参数:旧累加器值和元素本身。您只需忽略旧值并在元素上调用函数。

所以对于一个通用函数f(x),你可以这样做:

functools.reduce(lambda _,x:f(x),list,initializer=0)

所以你的情况是:

options = {}
functools.reduce(lambda _,phase:getattr(__import__(phase),phase)(options),flow,initializer=0)

编辑:

重读您的问题后,在我看来,每个函数都将options 作为输入,并生成应该传递给下一个函数的“新”选项。那么第一个函数的返回,就是下一个函数的lambda的第一个参数。所以你可以像这样折叠起来:

first_options = {}
functools.reduce(lambda options,phase:getattr(__import__(phase),phase)(options),flow,initializer=first_options)

这将导致相当于:

options_0 = first_options
options_1 = getattr(__import__(phase),flow[0])(options_0)
options_2 = getattr(__import__(phase),flow[1])(options_1)
# ...
return options_n

但这当然发生在内部reduce。

【讨论】:

  • 使用选项作为初始化器怎么样?
  • @CelixOderix:你的意思是 old 函数会为下一个函数创建 new 选项?
  • 是的!完美,这正是我想要做的!
【解决方案2】:

所以 reduce 接受一个函数,比如reduce_func,它接受 2 个参数。当它遍历一个列表时,它将前两项作为reduce_func 的参数进行第一次调用,然后在每个后续调用中,使用返回值作为第一个参数,列表中的下一个值作为第二个参数.这意味着,对您而言,reduce_func 需要如下

def reduce_func(param, f):
   return f(param)

并且您的列表需要如下:

[options, func1, func2, func3, func4]

现在,我使用了函数列表并且没有使用导入。代替f,您可以将[module].[function] 作为字符串传入(将参数称为func_str),然后在reduce_func 内部进行一些拆分和设置。

【讨论】:

    猜你喜欢
    • 2018-05-08
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    相关资源
    最近更新 更多