将递归函数更改为迭代

时间:2018-09-26 07:45:15

标签: python-3.x iterator

我想创建一个<ufunc>链接器,这是我使用functors.reduce函数实现的。例如:

from functools import reduce
fns1 = [np.cos, np.sin, np.tan]
x = reduce(  lambda f, f1: lambda m: f1(f(m)) , fns1, lambda m: m )
x(0.5)

尽管这很简单,但我想使代码更具可读性。所以我生成了一个迭代版本:

def fnLong(fnList):

    curFn = lambda m: m
    for f in fnList:
        currF = lambda m: f(currF(m))

    return currF

此函数实际上会创建一个无限循环。我认为这两个功能应该完全相同,但显然不一样。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

该问题源自lambda表达式,因为它在调用时已解决。在lambda内创建一堆for loop时,此功能会导致各种问题。在您的代码中,您可以在lambda内的lambda内使用for loop,然后返回生成的嵌套lambda以便以后调用。

您可以这样解决问题:

def fnLong(fnList):

    currF = lambda m: m
    for f in fnList:
        currF = lambda m, f=f, currF=currF: f(currF(m))

    return currF
添加了

currF=currFf=f,以在创建lambda期间为for loop中每个lambda表达式指定自变量(绑定自变量)。该解决方案之所以有效,是因为参数的默认值是在函数创建(定义)期间而不是在函数调用期间创建的。 currF=currF允许避免递归,f=f允许避免仅使用fnList中的最后一个函数。

我认为很难说这个版本是否比原始版本更具可读性。