Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factorial function using lambda

Tags:

python

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
like image 654
RoiMinuit Avatar asked Dec 30 '22 18:12

RoiMinuit


2 Answers

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
like image 164
Mihai Alexandru-Ionut Avatar answered Jan 02 '23 07:01

Mihai Alexandru-Ionut


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
like image 40
chepner Avatar answered Jan 02 '23 06:01

chepner