代码之家  ›  专栏  ›  技术社区  ›  Dan Lorenc

python lambda问题

  •  15
  • Dan Lorenc  · 技术社区  · 15 年前

    这是怎么回事?我正在尝试创建函数列表:

    def f(a,b):
        return a*b
    
    funcs = []
    
    for i in range(0,10):
        funcs.append(lambda x:f(i,x))
    

    这不是我所期望的。我希望列表的作用如下:

    funcs[3](3) = 9
    funcs[0](5) = 0
    

    但列表中的所有函数似乎都相同,并将固定值设置为9:

    funcs[3](3) = 27
    funcs[3](1) = 9
    
    funcs[2](6) = 54
    

    有什么想法吗?

    5 回复  |  直到 15 年前
        1
  •  19
  •   Ryan    15 年前

    python中的lambda是闭包…在lambda被计算之前,不会对您提供的参数进行计算。在那个时候,不管怎样,我=9,因为您的迭代已经完成了。

    您正在寻找的行为可以通过functools实现。

    import functools
    
    def f(a,b):
        return a*b
    
    funcs = []
    
    for i in range(0,10):
        funcs.append(functools.partial(f,i))
    
        2
  •  13
  •   Alex Martelli    15 年前

    是的,通常的“范围问题”(实际上是一个比您想要的问题晚的绑定,但它通常是用这个名称调用的)。你已经得到了两个最好的(因为最简单的)答案——“假违约” i=i 解决方案,以及 functools.partial 所以我只给经典的三款中的第三款,“工厂lambda”:

    for i in range(0,10):
        funcs.append((lambda i: lambda x: f(i, x))(i))
    

    我个人会同意的 我=我 如果在 funcs 意外使用2个参数而不是1调用,但是当需要比预先绑定一个参数更丰富一点的内容时,工厂函数方法值得考虑。

        3
  •  10
  •   ars    15 年前

    只有一个 i 它绑定到每个lambda,与您的想法相反。这是一个常见的错误。

    获得你想要的东西的一种方法是:

    for i in range(0,10):
        funcs.append(lambda x, i=i: f(i, x))
    

    现在您要创建一个默认参数 在每个lambda闭包中,并将当前 价值 循环变量的 .

        4
  •  2
  •   Community arnoo    7 年前

    所有的羊羔最后都被绑在最后一只羊羔身上。请参阅此问题以获得更长的答案:

    How do I create a list of Python lambdas (in a list comprehension/for loop)?

        5
  •  2
  •   gahooa    15 年前

    考虑到 i == 9

    与任何优秀的python函数一样,它将在定义的范围内使用变量的值。也许 lambda: varname (因为它是语言构造)绑定到名称,而不是值,并在运行时计算该名称?

    类似:

    i = 9
    def foo():
        print i
    
    i = 10
    foo()
    

    我很想知道我的答案是正确的