3

I'm doing a complicated hack in Python, it's a problem when you mix for+lambda+*args (don't do this at home kids), the boring details can be omited, the unique solution I found to resolve the problem is to pass the lambda object into the self lambda in this way:

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

It's possible?, thanks a lot.

3
  • Duplicate: stackoverflow.com/questions/481692/… Commented Jan 7, 2010 at 22:08
  • I saw it, but I do not want to do recursion, and this solutions has a a lot ofuscation to do recursion... Some simplest solution? Commented Jan 7, 2010 at 22:20
  • Without the boring details this appears to be little more than a decorator. Wouldn't that be simpler? Commented Jan 7, 2010 at 23:11

5 Answers 5

8

You are looking for a fixed-point combinator, like the Z combinator, for which Wikipedia gives this Python implementation:

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

Z takes one argument, a function describing the function you want, and builds and returns that function.

The function you're looking to build is:

Z(lambda f: lambda x=x, *y: foo(x, y, f))
Sign up to request clarification or add additional context in comments.

Comments

4

While your question is genuinely weird, try something like:

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

1 Comment

I'm glad this works for you, but it doesn't do what you asked for. This creates a second function that has a reference to the first function, not a reference to itself. The two functions behave differently and have different arguments.
0

If you want to refer to it, you'll have to give it a name

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

such is the way of the snake

2 Comments

This definition grants the power of flowing through the Child-like Empress. However, be warned, you may only use this with Her permission. Tu, was du willst.
This does not work, because the for loop gives unconsistency to the variable naming.
0

The easiest way is to write a separate function to create the lambda.

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

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

This works just like gnibbler's suggestion but can be used in a for loop.

EDIT: I wasn't joking. It really works!

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

3 Comments

If a lambda is simply an anonymous function, and this technique has to bind it to name, I would think it wouldn't need to use lambda, and is probably harder to read because of it.
A function with just a lambda operates exacty equal than a lamba, this resolves nothing.
Yes I try it and much more, finally functools.partial was the solution
0

I don't understand why you want to do this with lambda.

lambda: creates a function object that does not have a name

def: creates a function object that does have a name

a name: very useful for calling yourself

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

Doesn't this do exactly what you requested? I even called it selflambda. If it doesn't do what you want, would you please explain why it doesn't?

EDIT: Okay, Jason Orendorff has pointed out that this won't work, because each time through the loop, the name selflambda will be rebound to a new function, so all the function objects will try to call the newest version of the function. I'll leave this up for the educational value, not because it is a good answer.

2 Comments

steveha: Look closely. What does the selflambda in that function refer to after the next loop iteration?
Hmmm. Okay, so that is why the answer he accepted involves functional.partial(). I'll update my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.