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.
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
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
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
This would be my answer
factorial = lambda num: 1 if num <= 1 else num * factorial(num-1)
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.
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
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
Another way:
factorial = lambda x: x if x==1 else x * factorial(x-1)
Related
How do I go about computing a factorial of an integer in Python?
The easiest way is to use math.factorial (available in Python 2.6 and above):
import math
math.factorial(1000)
If you want/have to write it yourself, you can use an iterative approach:
def factorial(n):
fact = 1
for num in range(2, n + 1):
fact *= num
return fact
or a recursive approach:
def factorial(n):
if n < 2:
return 1
else:
return n * factorial(n-1)
Note that the factorial function is only defined for positive integers, so you should also check that n >= 0 and that isinstance(n, int). If it's not, raise a ValueError or a TypeError respectively. math.factorial will take care of this for you.
On Python 2.6 and up, try:
import math
math.factorial(n)
Existing solution
The shortest and probably the fastest solution is:
from math import factorial
print factorial(1000)
Building your own
You can also build your own solution. Generally you have two approaches. The one that suits me best is:
from itertools import imap
def factorial(x):
return reduce(long.__mul__, imap(long, xrange(1, x + 1)))
print factorial(1000)
(it works also for bigger numbers, when the result becomes long)
The second way of achieving the same is:
def factorial(x):
result = 1
for i in xrange(2, x + 1):
result *= i
return result
print factorial(1000)
def factorial(n):
if n < 2:
return 1
return n * factorial(n - 1)
For performance reasons, please do not use recursion. It would be disastrous.
def fact(n, total=1):
while True:
if n == 1:
return total
n, total = n - 1, total * n
Check running results
cProfile.run('fact(126000)')
4 function calls in 5.164 seconds
Using the stack is convenient (like recursive call), but it comes at a cost: storing detailed information can take up a lot of memory.
If the stack is high, it means that the computer stores a lot of information about function calls.
The method only takes up constant memory (like iteration).
Or using a 'for' loop
def fact(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
Check running results
cProfile.run('fact(126000)')
4 function calls in 4.708 seconds
Or using the built-in function math
def fact(n):
return math.factorial(n)
Check running results
cProfile.run('fact(126000)')
5 function calls in 0.272 seconds
If you are using Python 2.5 or older, try
from operator import mul
def factorial(n):
return reduce(mul, range(1, n+1))
For newer versions of Python, there is factorial in the math module as given in other answers here.
def fact(n):
f = 1
for i in range(1, n + 1):
f *= i
return f
Another way to do it is to use np.prod shown below:
def factorial(n):
if n == 0:
return 1
else:
return np.prod(np.arange(1,n+1))
Non-recursive solution, no imports:
def factorial(x):
return eval(' * '.join(map(str, range(1, x + 1))))
You can also make it in one line recursively if you like it. It is just a matter of personal choice. Here we are using inline if else in Python, which is similar to the ternary operator in Java:
Expression1 ? Expression2 : Expression3
One line function call approach:
def factorial(n): return 1 if n == 0 else n * factorial(n-1)
One line lambda function approach:
(although it is not recommended to assign lambda functions directly to a name, as it is considered a bad practice and may bring inconsistency to your code. It's always good to know. See PEP8.)
factorial = lambda n: 1 if n == 0 else n * factorial(n-1)
I am a middle school student and just started learning about functions. This code is about exponents, but I cannot use import math. Is there a way to make this code into a one-liner or make it shorter?
def power(a, n):
x = 1
if n == 0:
print(1)
elif n > 0:
for i in range(n):
x = x * a
else:
for i in range(-n):
x = x * a
return x
print(power(2, 5))
You can use the pow function instead of "x = x * a". Also even if you don't want to use that function, you can simplify it as "x *= a".
You could look into recursive functions, they are a bit tricky at first but are a good brain exercise.
A recursive power function would look like that :
def power(a, n):
if n == 0:
return 1
elif n == 1:
return a
else:
return a * power(a, n-1)
You can use the in-built operator **.
Example:
print(2**2) # Will return 4
Use the ** operator directly:
print(2 ** 5)
You can use this
**
which will return the value of 4 to the power of 3 (same as 4 * 4 * 4):
You can use ** This is an exponentiation operator.
def power(a, n):
return a**n
print(power(2, 5))
or simply use lambda function. You can read about it here.
print((lambda x,y:x**y)(2,5))
If you want to shorten your function with one line, you can use lambda statements like this: Shortening code with lambda statement in python
And you can use the ** builtin operator in place of multiplying the number over and over in a loop. So for example, 5**4 is equivalent to 5 * 5 * 5 * 5 and will give the exact same output.
P.S. I am also just beginning with programming, so I might not have the best answer.
If the goal is to use your own function. You can shorter an if with:
value_when_true if condition else value_when_false;
Putting a simple if-then-else statement on one line
I can see your overall need is to get the power of x.
If you can't use import math, then go with the inbuilt arithmetic operator for exponential that is **
Ex. You need 5 to the power 4 then code will be
print(5**4) # In one line
def power(b,n):
n=abs(n)
print(b**n)
print(power(2,-5))
well how about this here you can use the abs function to convert negative number to positive so no need for extra code simple use of ** can do everything
I'm trying to create a function that takes a value x, and creates a pattern like this with n+1 square root terms: sqrt(x)^sqrt(x)^sqrt(x)^sqrt(x)^sqrt(x)...
def func(x,n):
a = x**0.5
i = 0
while i < n:
a = a ** (x**0.5)
i += 1
print a
For example using x = 2, the function does not converge (to 2), but increases exponentially in some way, I don't understand why.
For the first iteration (i=0) it seems to be correct, as it calculates, sqrt(2)^sqrt(2), but for the second iteration (i=1) it gives me 2.0, and it keeps increasing.
Thanks!
The above answer by #interjay illustrates what the problem is with the iterative method. As an alternative, you could also use a recursive method to calculate this
from math import sqrt
def fun(x,n):
if n == 0:
return sqrt(x)
else:
return sqrt(x) ** fun(x, n-1)
>>> fun(2,2)
1.7608395558800285
>>> fun(2,3)
1.8409108692910108
>>> fun(2,10)
1.988711773413954
>>> fun(2,100)
2.0000000000000004
For sqrt(x)^sqrt(x)^sqrt(x)... to converge, the exponentiation needs to be treated as right-associative, i.e. sqrt(x)^(sqrt(x)^(sqrt(x)^...)). But your code is calculating it as left-associative: ((...^sqrt(x))^sqrt(x))^sqrt(x).
You need to switch the order of terms in
a = a ** (x**0.5)
to
a = (x**0.5) ** a
def sumdigits(number):
if number==0:
return 0
if number!=0:
return (number%10) + (number//10)
this is the function that I have. However its only give the proper sum of 2 digit numbers. How can i get the sum of any number.
Also would my function count as recursion
def main():
number=int(input("Enter a number :"))
print(sumdigits(number))
main()
No, it is not recursive as you are not calling your function from inside your function.
Try:
def sumdigits(number):
if number == 0:
return 0
else:
return (number%10) + sumdigits(number//10)
Recursion is a way of programming or coding a problem, in which a function calls itself one or more times in its body.
Usually, it is returning the return value of this function call. If a function definition fulfils the condition of recursion, we call this function a recursive function.
A recursive function has to terminate to be used in a program.
Usually, it terminates, if with every recursive call the solution of the problem is downsized and moves towards a base case.
A base case is a case, where the problem can be solved without further recursion. (a recursion can lead to an infinite loop, if the base case is not met in the calls).
For this problem, the "base case" is:
if number == 0:
return 0
A simple recursive function for sum all the digits of a number is:
def sum_digits(number):
""" Return the sum of digits of a number.
number: non-negative integer
"""
# Base Case
if number == 0:
return 0
else:
# Mod (%) by 10 gives you the rightmost digit (227 % 10 == 7),
# while doing integer division by 10 removes the rightmost
# digit (227 // 10 is 22)
return (number % 10) + sumdigits(number // 10)
If we run the code we have:
>>>print sum_digits(57) # (5 + 7) = 12
12
>>>print sum_digits(5728) # (5 + 7 + 2 + 8) = 22
22
For a function to be recursive, it must call itself within itself. Furthermore, since your current one does not do this, it is not recursive.
Here is a simple recursive function that does what you want:
>>> def sumdigits(n):
... return n and n%10 + sumdigits(n//10)
...
>>> sumdigits(457)
16
>>> sumdigits(45)
9
>>> sumdigits(1234)
10
>>>
You don't make a recursive step (calling sumdigits() inside)!
I believe this is what you are looking for:
def sum_digits(n):
if n < 10:
return n
else:
all_but_last, last = n // 10, n % 10
return sum_digits(all_but_last) + last
While recursion is a clever way to go, I'd generally stay away from it for performance and logic reasons (it can get complex pretty quick). I know it's not the answer you are looking for but I'd personally stick to something like this or some kind of loop:
def sumdigits(number):
return sum(map(int, str(number)))
Good luck!
I was working on this recently hope it will help someone in future
def digit(n):
p=0
for i in str(n):
p += int(i)
return p
def superDigit(n):
if n==0:
return 0
return digit(digit(digit(digit(n))))
Here's a solution to summing a series of integer digits that uses ternary operators with recursion and some parameter checking that only happens the first time through the function. Some python coders may consider this less pythonic (using ternary expressions), however, it demonstrates how to use recursion, answering the original question, while introducing ternary operators to combine a few multi-line if/else statements into simple math.
Note that:
int * True = int, whereas int * False = 0
float * True = Float, whereas float * False = 0
"Text" * True = "Text", but "Text" * False = ""; but also
"Text" * 0 = "", whereas "Text" * 3 = "TextTextText"
"Text" * float = Error; whereas "Text" * int = Error
The one-line if/else statement reads as follows:
Expression_if_True if Condition_to_Check else Expression_if_False
def digitSum2(n = 0, first = True):
if first:
first = False
if type(n) != int or n < 0:
return "Only positive integers accepted."
return (n * (n < 10) + (n % 10 + digitSum2(n // 10, first)) * (n >= 10)) if (n > 0) else 0
I've been stucked on this question for a really long time.
I've managed to do a single recursive factorial.
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
Double factorial
For an even integer n, the double factorial is the product of all even positive integers less than or equal to n. For an odd integer p, the double factorial is the product of all odd positive integers less than or equal to p.
If n is even, then n!! = n*(n - 2)*(n - 4)*(n - 6)* ... *4*2
If p is odd, then p!! = p*(p - 2)*(p - 4)*(p - 6)* ... *3*1
But I have no idea to do a double factorial. Any help?
from functools import reduce # only in Python 3
reduce(int.__mul__, range(n, 0, -2))
Isn't that just the same as the factorial with a different ending condition and a different parameter to the recursion call?
def doublefactorial(n):
if n <= 0:
return 1
else:
return n * doublefactorial(n-2)
If n is even, then it will halt when n == 0. If n is odd, then it will halt when n == -1.
The problem here is that the double factorial is defined for negative real numbers (-1)!! = 1, (-3)!! = -1 (even negative integers (such -2, -4, ...) should have solution as +/- inf) so... something is smelling bad in all solutions for negative numbers. If one want to define the double factorial for al reals those solutions don't work. The solution is to define the double factorial using gamma function.
import scipy.special as sp
from numpy import pi
def dfact(x):
n = (x + 1.)/2.
return 2.**n * sp.gamma(n + 0.5)/(pi**(0.5))
It works! :D
Starting Python 3.8, we can use the prod function from the math module which calculates the product of all elements in an iterable, which in our case is range(n, 0, -2):
import math
math.prod(range(n, 0, -2))
Note that this also handles the case n = 0 in which case the result is 1.
My version of the recursive solution, in one line:
dfact = lambda n: (n <= 0) or n * dfact(n-2)
However, it is also interesting to note that the double factorial can be expressed in terms of the "normal" factorial. For odd numbers,
n!! = (2*k)! / (2**k * k!)
where k = (n+1)/2. For even arguments n=2k, although this is not consistent with a generalization to complex arguments, the expression is simpler,
n!! = (2k)!! = 2*k * k!.
All this means that you can write code using the factorial function from the standard math library, which is always nice:
import math
fact = math.factorial
def dfact(n):
if n % 2 == 1:
k = (n+1)/2
return fact(2*k) / (2**k * fact(k))
else:
return 2**k * fact(k)
Now, this code is obviously not very efficient for large n, but it is quite instructive. More importantly, since we are dealing with standard factorials now, it is a very good starting point for optimizations when dealing with really large numbers. You try to use logarithms or gamma functions to get approximate double factorials for large numbers.
def doublefactorial(n):
if n in (0, 1):
return 1
else:
return n * doublefactorial(n-2)
should do it.
def double_fact(number):
if number==0 or number==1:
return 1
else:
return number*double_fact(number-2)
I think this should work for you.
I hope I understand it correctly, but will this work
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n-2)
reduce(lambda x,y: y*x, range(n,1,-2))
Which is basically the same as the simple iterative version:
x = n
for y in range(n-2, 1, -2):
x*=y
Obviously you can also do it recursively, but what's the point ? This kind of example implemented using recursivity are fine when using all recursive languages, but with imperative language it's always making simple tools like recursivity looking more complex than necessary, while recursivity can be a real simplifier when dealing with fundamentally recursive structures like trees.
def doublefactorial(n):
if n <= 0:
return 1
else:
return n * doublefactorial(n-2)
That should do it. Unless I'm misunderstanding