'Writing a Factorial function in one line in Python
I am looking to improve my coding by performing the same code in different ways, this not only is to help me become better at coding but also understand different people's code and their coding style. Can someone explain how I might be able to right a factorial function similar to the one posted below in one line? Also using lambda functions are welcome too.
def factorial(number):
fact = 1
for i in range(1, number + 1):
fact *= i
return fact
I know I can write this recursively but I have chosen not to do it that way.
Solution 1:[1]
Here is my one-liner solution without importing anything.
def factorial(n: int):
return n * factorial(n - 1) if n > 1 else 1
It recurses until the input number is 1, where it finally returns the result (in the case of n=0, it returns 1 since 0!=1). The solution also uses the ternary operator fit an if...else
into one line.
Note that python has a maximum recursion, so factorial(x)
where x >= 999 will result in a RecursionError
Solution 2:[2]
You can use reduce
to write a factorial function.
from operator import mul
# from functools import reduce # Python3 only
def factorial(x):
return reduce(mul, range(1, x + 1), 1)
factorial(5) # 24
You can also import it from the math
module which additionally raises exceptions for negative and non-integral numbers.
from math import factorial
Solution 3:[3]
Similar to YulkyTulky's answer, it is also possible to write the one liner just using Boolean logic and without an if
.
factorial = lambda x : x and x * factorial(x - 1) or 1
The x and x * factorial(x - 1)
part returns a value as long as x is not zero, but when x is zero, the function returns 1, ending the recursion.
factorial(4) # 24
Solution 4:[4]
You can write a one-line lambda function with the help of the built-in function reduce
(although you will have to import reduce
from functools
if you upgrade to Python 3.x). Note that the last argument sets the initial value to 1
so that 0!
can still work:
lambda x: reduce(int.__mul__, range(1, x + 1), 1)
so that:
print((lambda x: reduce(int.__mul__, range(1, x + 1), 1))(4))
would output 24
, for example.
Solution 5:[5]
Another way:
factorial = lambda x: x if x==1 else x * f(x-1)
Solution 6:[6]
So the simplest option (i think) would be to create a string that you can then evaluate using the built in eval method, so we are essentially eval('1 * 2 * 3...')
factorial = lambda num: eval('*'.join([str(each) for each in range(1, num + 1)]))
print(factorial(3))
if you would want a more formatted solution you could simply create a formatted-string with your desired format, what i mean is:
factorial_formatted = lambda num: '{}! = {}'.format(
num, eval('*'.join([str(each) for each in range(1, num + 1)])))
print(factorial_formatted(3))
output respectively would be: 6, 3! = 6
Solution 7:[7]
Factorials in Python
factorial = math.gamma(n + 1)
Example Program
import math
def get_factorial(n):
try:
print(math.gamma(n + 1))
except ValueError:
print("Domain Error: ?n /? ?")
except OverflowError:
print("Overflow Error")
except Exception as e:
print(f"{e}")
n = float(input("Enter n for n! : "))
get_factorial(n)
Note: works for real numbers e.g. -2.90! = 5.56
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Alex Wilkins |
Solution 2 | |
Solution 3 | David Buck |
Solution 4 | |
Solution 5 | Matias Lopez |
Solution 6 | unityGuy |
Solution 7 | Catterall |