Reputation: 414
I am trying to implement the function below into one line of lambda code.
def fac(num):
num = int(num)
if num > 1:
return num * fac(num - 1)
else:
return 1
I have constructed a lambda statement, but I keep getting syntax error:
z = lambda z: if (z > 1) z * (z-1) else 1
Upvotes: 4
Views: 1116
Reputation: 12222
The complete solution as a lambda is this one:
factorial = lambda n: 1 if n <= 1 else factorial(n - 1) * n
There are three problems with your code:
a) You are calling your function z
, and your parameter z
as well. You cannot do that if you are planning to call recursively the function itself, though you're not doing that in your code.
b) Recursive functions have a regular case and a base case. The base case, the end of recursion, is reached when the parameter goes down to 1, while in the regular case you call n * factorial(n - 1).
c) You used the ternary operator in an incorrect order, probably thinking in ternary operators present in C and others, in which you have: <conditional-expression> ? <expression1> : <expression2>
, while in Python the syntax is <expression1> if <conditional-expression> else <expression2>
.
Upvotes: 1
Reputation: 532093
Don't use a lambda expression where you really want a def
statement. Lambda expressions produce anonymous functions. An anonymous function can't have a reference to itself, and recursion in Python relies on having such a refernce (usually in the form of a global or nonlocal variable).
That said, you can (using a bit of fancy lambda calculus) create a recursive function from an anonymous function. The trick is that your anonymous function will take two arguments: one is the "real" argument, the other is a reference to the function you want to call "recursively".
lambda n, f: n*f(n-1) if n else 1
There's no recursive call here; your anonymous function simply multiplies n
by the return value of some function f
called on n-1
when n
is greater than 0. (We're assuming that n > 0
.) Your function doesn't know or care what f
is; it just receives it as an argument.
The thing that gives us recursion is a single "universal" recursive function called fix
. It takes your two-argument function and returns a single-argument function that calls your original function with its wrapper passed as the second argument:
def fix(g):
def wrapper(n):
return g(n, wrapper)
return wrapper
fact = fix(lambda n, f: n*f(n-1) if n else 1)
Then
>>> fact(0)
1
>>> fact(3)
6
>>> fact(6)
720
Upvotes: 2
Reputation: 48417
First of all, you can't refer to a global name z
when there is a local variable (the parameter) by the same name.
Thus, we will declare a lambda statement called func
and use the ternary
operator in the good way.
func = lambda z: z * func(z-1) if (z > 1) else 1
Output
> func(5)
120
Upvotes: 6