RoiMinuit
RoiMinuit

Reputation: 414

Factorial function using lambda

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

Answers (3)

Baltasarq
Baltasarq

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

chepner
chepner

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

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

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

Related Questions