动态创建 lambda 函数列表,其中每个下一个函数使用前一个函数

我想创建lambdas一个给定大小n的列表(因此手动分配不起作用),其中每个元素取决于先前的函数并且它在列表中索引。


我尝试过各种类似的东西:


n = 3

func_list = [lambda x : 1]

for k in range(1,n):

    func_list.append(lambda x : func_list[k-1](x) * (x+k))

print(list(map(lambda f : print(f(1)), func_list)))

但在所有尝试中,我都收到了关于recursion深度的错误消息:


RecursionError                            Traceback (most recent call last)

<ipython-input-296-f35123a830c4> in <module>

      2 for k in range(1,3):

      3     func_list.append(lambda x : func_list[k-1](x) * (x+k))

----> 4 print(list(map(lambda f : print(f(1)), func_list)))


<ipython-input-296-f35123a830c4> in <lambda>(f)

      2 for k in range(1,3):

      3     func_list.append(lambda x : func_list[k-1](x) * (x+k))

----> 4 print(list(map(lambda f : print(f(1)), func_list)))


<ipython-input-296-f35123a830c4> in <lambda>(x)

      1 func_list = [lambda x : 1]

      2 for k in range(1,3):

----> 3     func_list.append(lambda x : func_list[k-1](x) * (x+k))

      4 print(list(map(lambda f : print(f(1)), func_list)))


 ... last 1 frames repeated, from the frame below ...


<ipython-input-296-f35123a830c4> in <lambda>(x)

      1 func_list = [lambda x : 1]

      2 for k in range(1,3):

----> 3     func_list.append(lambda x : func_list[k-1](x) * (x+k))

      4 print(list(map(lambda f : print(f(1)), func_list)))


RecursionError: maximum recursion depth exceeded


慕姐8265434
浏览 113回答 2
2回答

斯蒂芬大帝

正如Elegant Odoo 的回答所指出的,Python lambdas 通过引用捕获变量。搜索答案时您可能会听到的另一个术语是“后期绑定”,这意味着只有在执行 lambda 时才会将 lambda 内的变量绑定到它的实际值。结果,您创建的所有 lambda 函数都具有相同的(和最终的)值k,这会导致无限递归。虽然exec基于 - 的方法是有效的,但我认为大多数人都会同意exec在实际代码中应该避免这种做法。对此的替代解决方案是通过函数创建 lambda 函数以强制早期绑定:n = 3func_list = [lambda x: 1]def create_fn(k_val):&nbsp; &nbsp; return lambda x: func_list[k_val - 1](x) * (x + k_val)for k in range(1, n):&nbsp; &nbsp; func_list.append(create_fn(k))print(list(map(lambda f: f(1), func_list)))当您调用create_fnwith 时k, 的当前值将k传递给 name 下的函数k_val。然后k_val将 lambda 函数中的k_val变量绑定到 范围内的变量,并在调用它时create_fn使用 的值。k

婷婷同学_

一个很好的案例来解释 Reference 和 Value 之间的区别:让我解释一下为什么会发生这种情况,以了解发生了什么让我们使用普通函数,以便我们可以调试 K 的值:&nbsp; &nbsp; n = 3&nbsp; &nbsp; func_list = [lambda x : 1]&nbsp; &nbsp; for k in range(1,n):&nbsp; &nbsp; &nbsp; &nbsp; def f(x):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('K is: ', k)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return func_list[k-1](x) * (x + k)&nbsp; &nbsp; &nbsp; &nbsp; func_list.append(f)&nbsp; &nbsp; # just print will be enough to cause error&nbsp; &nbsp; print(func_list[2])输出是:&nbsp; &nbsp; K is : 2&nbsp; &nbsp; K is : 2&nbsp; &nbsp; K is : 2&nbsp; &nbsp; K is : 2&nbsp; &nbsp; K is : 2&nbsp; &nbsp; ....&nbsp; &nbsp; ....&nbsp; &nbsp; ....&nbsp; &nbsp; ....&nbsp; &nbsp; RecursionError: maximum recursion depth exceeded while calling a Python object您在所有方法中使用相同的变量(对 value 的引用)。K 引用循环生成的值 2。在循环 make 结束后进行演示k = 5,这将引发错误index out of range。一个简单的解决方案exec:&nbsp; &nbsp; n = 3&nbsp; &nbsp; func_list = [lambda x: 1]&nbsp; &nbsp; for k in range(1, n):&nbsp; &nbsp; &nbsp; &nbsp; # here you are not using variable k we are using the value it's like&nbsp; &nbsp; &nbsp; &nbsp; # we are rewriting it to code every time but is not you who typing it's the compute -_^&nbsp; &nbsp; &nbsp; &nbsp; exec('func_list.append(lambda x : func_list[{k}-1](x) * (x + {k}))'.format(k=k))&nbsp; &nbsp; # lambda print(f(1)) will create [None, None, None] I removed the print&nbsp; &nbsp; print(list(map(lambda f: f(1), func_list)))输出:&nbsp; &nbsp; [1, 2, 6]诅咒上述解决方案适用于您的情况,因为K它只是一个简单Integer 的假设,K它是一个非常复杂的对象,具有复杂的属性和私有变量。为了达到同样的目的,您需要重建对象。&nbsp; &nbsp; # we need to consract another object using the value&nbsp; &nbsp; exec('... KClass({}, {}, {}) ...'.format(k.attr1, k.attr2, k.attr2))KClass使用您的属性 Object 的成像XClass将需要构造两个 object k and x。所以使用exec工厂模式是不实际的更好的方法来处理这个问题:&nbsp; &nbsp; n = 3&nbsp; &nbsp; func_list = [lambda x: 1]&nbsp; &nbsp; def method_factory(k):&nbsp; &nbsp; &nbsp; &nbsp; # here K reference it's not the same K reference that is created&nbsp; &nbsp; &nbsp; &nbsp; # in loop there are different but with the alias K&nbsp; &nbsp; &nbsp; &nbsp; return lambda x: func_list[k - 1](x) * (x + k)&nbsp; &nbsp; for k in range(1, n):&nbsp; &nbsp; &nbsp; &nbsp; func_list.append(method_factory(k))&nbsp; &nbsp; print(list(map(lambda f: f(1), func_list)))为什么会这样,因为当您调用method_factory它时,它将创建自己的范围,其中包含一个带有别名的引用,K该引用指向value的引用指向的引用相同。Kloop希望你明白这一切都是关于reference和的scopes。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python