如何在python列表中附加一个lambda?

时间:2019-04-12 06:39:33

标签: python lambda append

我正在尝试创建一个程序,该程序创建格式为y=mx+b的lambda函数列表,其中'm'和'b'是预定值

我的总体目标是实现

的功能
  • 拍照
  • 找到上面的线
  • 以纯色将它们扩展到整个图片中

基本上,如果您知道这是什么,例如霍夫变换

一旦有了用于特定图像的线条,就可以创建一个lambda函数来表示线条的斜率及其起点。我遇到了无法将lambda函数添加到列表的问题。

我已经尝试过了:

if __name__ == "__main__":
  nums = []
  for i in range(10):
    j = lambda x: x + i
    nums.append(j)
  for i in nums:
    print(i(1))

这是我遇到的错误:

Traceback (most recent call last):
  File "C:/Users/me/.PyCharmCE2018.3/config/scratches/scratch_3.py", line 7, in <module>
    print(i(1))
  File "C:/Users/me/.PyCharmCE2018.3/config/scratches/scratch_3.py", line 4, in <lambda>
    j = (lambda x: x + i)
TypeError: unsupported operand type(s) for +: 'int' and 'function'

5 个答案:

答案 0 :(得分:2)

问题是您创建的lambda引用了活动堆栈帧中的i的当前值。当您以后在第二个i循环中重复使用for时,它将绑定到列表中的lambda。当以i(1)的形式调用时,lambda会尝试求值1 + i,其中i是lambda,因此当然会出现错误。

可能您想要的是在创建lambda时冻结i的值。您可以通过替换以下内容来实现:

j = lambda x: x + i

具有:

j = (lambda y: lambda x: x + y)(i)

这通过将i的当前值绑定到lambda变量,然后立即应用该lambda来有效地捕获它,此后绑定保持固定。

答案 1 :(得分:1)

这将为您提供线索:

>>> i=1
>>> a=lambda x:x+i
>>> a(5)
6
>>> i=2
>>> a(5)
7

lambda在外部范围中使用i。在OP情况下,所有功能都相同。在最终循环中使用i使i是一个函数,而不是整数。将其更改为其他内容,使用i的最后一个值,您将发现所有功能都相同:

nums = []
for i in range(10):
    j = lambda x: x + i
    nums.append(j)
for f in nums:
    print(f(1))
10
10
10
10
10
10
10
10
10
10

解决方法是,使i为函数的参数,以将值捕获为局部变量:

nums = []
for i in range(10):
    j = lambda x,i=i: x + i
    nums.append(j)
for f in nums:
    print(f(1))
1
2
3
4
5
6
7
8
9
10

答案 2 :(得分:0)

您的 i 值已更改,这与您的想法不符。

首先创建lambda:

j = lambda x: x + i

希望,我将保持当前值(所以0、1、2等)。

然后执行它:

print(i(1))

您看到您如何命名第二个迭代器变量 i 吗?将其更改为 j 即可运行您的示例。为什么?由于python会在您的lambda中解析 i 的值,因此在执行时(而不是在定义时)会执行。因此,当您执行lambda( i(1))时,它将进入您的lambda主体并尝试 x + i 。然后它将查找 i ,其中现在包含您的lambda(而不是INTEGER!)。因此,您的问题。

您需要执行双重功能才能使其正常工作。试试这个:

if __name__ == "__main__":
  nums = []
  for i in range(10):
    def generate_lambda(i):
      return lambda x: x + i
    j = generate_lambda(i)
    nums.append(j)
  for i in nums:
    print(i(1))

为什么这样做?当您调用 generate_lambda 时,将存在带有您的INTEGER值的 i 变量。它将阴影变量 i ,该变量稍后将用于遍历lambda。而且,由于您永远不会在 generate_lambda 函数中修改 i 变量,因此它将永远保持这种状态。

答案 3 :(得分:0)

我认为您需要进一步了解lambda函数... 实际上,它的语法类似于:[ lambda arguments:expression ] 因此,问题在于表达式中有两个变量,因此您需要传递两个参数。 我并没有真正想要通过此功能实现什么,但是我想您需要为m和b使用两个参数。

在代码中,您需要初始化x并将其作为参数传递给lambda。

            nums = []
            x=0
            for i in range(10):
                j = lambda x,i : x + i
                nums.append(j)
            for i in nums:
                print(i(1,1))

答案 4 :(得分:0)

您可以使用operator.add和functools.partial而不使用lambda:

import operator
import functools


if __name__ == "__main__":
    nums = []

    for i in range(10):
        nums.append(functools.partial(operator.add, i))
    for i in nums:
        print(i(1))