【问题标题】:changing a recursive function to an iteration将递归函数更改为迭代
【发布时间】:2019-03-01 22:11:46
【问题描述】:

我想创建一个<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

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

【问题讨论】:

    标签: python-3.x iterator


    【解决方案1】:

    问题源于lambda 表达式,因为它是在调用时解决的。当您在 for loop 中创建一堆 lambdas 时,此功能会导致各种问题。在您的代码中,您在 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 中的最后一个函数。

    在我看来,很难说这个版本是否比原始版本更具可读性。

    【讨论】:

      猜你喜欢
      • 2010-10-06
      • 2013-04-15
      • 2010-12-19
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 2015-05-30
      相关资源
      最近更新 更多