【问题标题】:How can I evaluate an array of lambda functions如何评估一组 lambda 函数
【发布时间】:2019-07-22 18:56:21
【问题描述】:

我正在尝试编写一个函数,该函数将创建一个 lambda 函数列表,然后将一个数组传递给该列表。

我想出了如何对这个函数列表进行硬编码,但是,我似乎不知道如何使用 for 循环来创建列表。

例如,让我们使用一个非常简单的函数,我们将 A 的每个元素乘以 1,然后乘以 2,然后乘以 3,... 以此类推,这样每一行对应于 A 的元素,每一列对应于A乘以的数字。

import numpy as np
A = np.array([1,2,3,4])

def f():
    F3 = lambda x: 3*x
    F2 = lambda x: 2*x
    F1 = lambda x: 1*x
    F0 = lambda x: 0*x
    return lambda x: np.stack((F3(x),F2(x),F1(x),F0(x)),axis=1)

F = f()
F(A)

然后是我的输出。

array([[ 3,  2,  1,  0],
       [ 6,  4,  2,  0],
       [ 9,  6,  3,  0],
       [12,  8,  4,  0]])

上面的代码只用于 3*x。如果我想遵循 n*x 的模式,我会怎么做?我的基本想法如下(但是,这不起作用):

import numpy as np
A = np.array([1,2,3,4])

def _f():
    return lambda x: n*x
def f(N):
    F = []
    for n in range(N):
        F.append(lambda x: _f(n))
    return np.array(F)

F = f(5)
F(A)

在现实生活中,我的函数 _f() 要复杂得多。这背后的动机是我宁愿让我的程序只遍历每个 _f 一次,然后一次性执行计算 F(A)。

可以通过以下代码实现所需的输出,但是,每次调用 F 时都会遍历循环。

import numpy as np
A = np.array([1,2,3,4])

def _f(n,x):
    return n*x
def f(N,x):
    F = []
    for n in range(N):
        F.append(_f(n,x))
    return np.array(F)

F = f(5,A)
print(F.T)

这将返回:

[[ 0  1  2  3  4]
 [ 0  2  4  6  8]
 [ 0  3  6  9 12]
 [ 0  4  8 12 16]]

【问题讨论】:

    标签: python python-3.x numpy lambda


    【解决方案1】:

    这个循环坏了:

    for n in range(N):
        F.append(lambda x: _f(n))
    

    因为n在函数体中被延迟读取(所以所有存储的函数都从循环中读取nfinal值)。

    最简单的解决方法是将n 绑定为默认参数;默认参数在定义时被急切地绑定:

    for n in range(N):
        F.append(lambda x, n=n: _f(n))
                         ^^^^^ Changed part
    

    如果您想避免使用默认参数,请让您的工厂函数为您执行急切绑定:

    def _f(n):  # Now receives n as an argument to outer function
        return lambda x: n*x  # While inner function uses n from closure and x passed when called
    

    然后使用它:

    for n in range(N):
        F.append(_f(n))
    

    【讨论】:

    • 这解决了一部分,但是,我不知道如何将我的数组传递给我的函数。 F 以函数列表的形式出现。我的最终目标是以这样的方式编写函数 f ,即我可以将数组传递给它,并且它将对数组的每个元素执行每个函数。输出应该类似于我上面展示的迭代方法。
    • @Epsilon1024:我认为答案是转换为 tuple 并返回必要的函数,例如return lambda x: np.stack(tuple(reversed(F)), axis=1)。从未使用过numpy.stack(根据文档,您所拥有的对我来说并不合适),但我不是numpy 专家; return 在功能上应该是等效的,但是是动态大小的。
    【解决方案2】:

    _f(正确定义;它应该将n 作为一个参数,而不是将n 作为一个全局变量)已经是函数,当调用它时,它会返回您想要的函数。

    # Or _f = lambda n: lambda x: n * x
    def _f(n):
        return lambda x: n * x
    
    F = [_f(n) for n in range(N)]
    

    也就是说,您可以使用 functools.partial 完全避免 lambda 表达式及其范围问题:

    from functools import partial
    from operator import mul
    
    
    F = [partial(mul, n) for n in range(N)]
    

    【讨论】:

      猜你喜欢
      • 2018-11-05
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      相关资源
      最近更新 更多