The only way I can think of to do this amounts to giving the function a name:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
or alternately, for earlier versions of python:
fact = lambda x: x == 0 and 1 or x * fact(x-1)
Update: using the ideas from the other answers, I was able to wedge the factorial function into a single unnamed lambda:
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
So it's possible, but not really recommended!
Answer from Greg Hewgill on Stack OverflowThe only way I can think of to do this amounts to giving the function a name:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
or alternately, for earlier versions of python:
fact = lambda x: x == 0 and 1 or x * fact(x-1)
Update: using the ideas from the other answers, I was able to wedge the factorial function into a single unnamed lambda:
>>> map(lambda n: (lambda f, *a: f(f, *a))(lambda rec, n: 1 if n == 0 else n*rec(rec, n-1), n), range(10))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
So it's possible, but not really recommended!
without reduce, map, named lambdas or python internals:
(lambda a:lambda v:a(a,v))(lambda s,x:1 if x==0 else x*s(s,x-1))(10)
Videos
Maybe you need a Y combinator?
Edit - make that a Z combinator (I hadn't realized that Y combinators are more for call-by-name)
Using the definition of the Z combinator from Wikipedia
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
Using this, you can then define add as a completely anonymous function (ie. no reference to its name in its definition)
>>> add = Z(lambda f: lambda a, b: b if a <= 0 else 1 + f(a - 1, b))
>>> add(1, 1)
2
>>> add(1, 5)
6
Perhaps you should try the Z combinator, where this example is from:
>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
>>> fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
>>> Z(fact)(5)
120
First, you've got the base case wrong:
if n == 1:
return fn
After all, repeat(fn, 1) is just a function that applies fn once—that's fn.
Now, if the base case is when n == 1, the recursive case is almost always going to be something where you pass n - 1 to yourself.
So, what's the difference between repeat(fn, n) and repeat(fn, n-1)? If you can't figure it out, expand a simple case out in your head or on paper:
repeat(fn, 3)(x): fn(fn(fn(x)))
repeat(fn, 2)(x): fn(fn(x))
And now it's obvious: repeat(fn, n) is the same thing as fn(repeat(fn, n-1)), right? So:
else:
def new_fn(x):
return fn(repeat(fn, n-1)(x))
return new_fn
However, as filmor points out in the comments, it would be easier to use partial here:
def repeat3(fn, n, x):
if n == 1:
return fn(x)
else:
return fn(repeat3(fn, n-1, x))
def repeat(fn, n):
return functools.partial(repeat3, fn, n)
You can define this very simply in terms of your old repeat function:
repeat_new = lambda fn, n: lambda x: repeat(fn, n, x)
square_three_times = repeat_new (lambda x: x**2, 3)
print(square_three_times(3))