Lambda,将自己称为lambda定义

时间:2010-01-07 22:01:42

标签: python functional-programming lambda

我在Python中做了一个复杂的黑客攻击,当你混合使用+ lambda + * args时这是一个问题(不要在家里的孩子那里做),无聊的细节可以省略,我发现解决这个问题的独特解决方案问题是以这种方式将lambda对象传递给self lambda:

for ...
    lambda x=x, *y: foo(x, y, <selflambda>)

有可能吗?非常感谢。

5 个答案:

答案 0 :(得分:8)

您正在寻找一个fixed-point combinator,就像Z组合子一样,维基百科为此提供了Python实现:

Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))

Z接受一个参数,一个描述所需函数的函数,并构建并返回该函数。

您要构建的功能是:

Z(lambda f: lambda x=x, *y: foo(x, y, f))

答案 1 :(得分:4)

虽然您的问题确实很奇怪,但请尝试以下方法:

>>> import functools
>>> f = lambda selflambda, x=x, *y: foo(x, y, selflambda)
>>> f = functools.partial(f, f)

答案 2 :(得分:0)

如果你想引用它,你必须给它一个名字

bar=lambda x=x, *y: foo(x, y, bar)

这就是蛇的方式

答案 3 :(得分:0)

最简单的方法是编写一个单独的函数来创建lambda。

def mkfun(foo, x):
    f = lambda x=x, *y: foo(x, y, f)
    return f

for ...:
    ...mkfun(foo, x)...

这就像gnibbler的建议一样,但可以在for循环中使用。

编辑:我不是在开玩笑。它确实有效!

def foo(x, y, bar):
    print x
    if y:
        bar()  # call the lambda. it should just print x again.

# --- gnibbler's answer
funs = []
for x in range(5):
    bar=lambda x=x, *y: foo(x, y, bar)  # What does bar refer to?
    funs.append(bar)
funs[2](2, True)  # prints 2 4 -- oops! Where did the 4 come from?

# --- this answer
def mkfun(x, foo):
    bar = lambda x=x, *y: foo(x, y, bar)  # different bar variable each time
    return bar
funs = []
for x in range(5):
    funs.append(mkfun(x, foo))
funs[2](2, True)  # prints 2 2

答案 4 :(得分:0)

我不明白为什么要用lambda来执行此操作。

lambda:创建一个没有名称的函数对象

def:创建一个名称为

的函数对象

一个名字:给自己打电话非常有用

for ...
    def selflambda(x=x, *y):
        return foo(x, y, selflambda)
    ...

这不是你要求的吗?我甚至称之为selflambda。如果它没有做你想要的,你能解释它为什么没有吗?

编辑:好的,Jason Orendorff已经指出这不会起作用,因为每次循环时,名称selflambda都会被反弹到一个新函数,所以所有函数对象都会尝试调用最新版本的功能。我会留下这个教育价值,而不是因为这是一个很好的答案。