我在Python中做了一个复杂的黑客攻击,当你混合使用+ lambda + * args时这是一个问题(不要在家里的孩子那里做),无聊的细节可以省略,我发现解决这个问题的独特解决方案问题是以这种方式将lambda对象传递给self lambda:
for ...
lambda x=x, *y: foo(x, y, <selflambda>)
有可能吗?非常感谢。
答案 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
。如果它没有做你想要的,你能解释它为什么没有吗?
selflambda
都会被反弹到一个新函数,所以所有函数对象都会尝试调用最新版本的功能。我会留下这个教育价值,而不是因为这是一个很好的答案。