Function for factorial in Python - python

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)

Related

Python Program to Reverse Number Using Recursive Function problem

This code doesnt work for some reason but im not sure why
def rev(n):
if not n:
return 0
return rev(int(n/10))*10 + n%10
rev(512)
152
but when i save it in a specific variable and pass it through the function, it works.
why does this happen? anyone can help me with it?
def rev(n,r=0):
if not n:
return r
r = r*10 + n%10
return rev(int(n/10),r)
rev(512)
215
If you must use recursion to solve this problem, a possible way is to recursively compute the sum between each digit of n, multiplied by 10 to the power of n's order of magnitude at each recursion.
from math import log10
def rev(n):
if not n:
return 0
return int(n%10)*10**int(log10(n)) + rev(n//10)
As a side note, if you don't have to use recursion there are much simpler ways of doing this with str processing.
def rev(n,r=0):
if not n:
return r
r = r*10 + n%10
return rev(int(n/10),r)
#the above code can reverse the number digit by digit,bringing it forward;
def rev(n):
if not n:
return 0
return rev(int(n/10))*10 + n%10
#this code will do some other thing;
#once try for few examples;
#preferable 1234;
#you can get the differences of bith the algo

How to avoid memory error when using recursion? (Fibonacci Numbers)

I have the following exercise:
'''FIBONACCI
Compute the n'th Fibonacci number fib(n), defined recursively:
fib(0) == 0, fib(1) == 1, fib(n) = fib(n - 1) + fib(n - 2)
Input:
A single line containing an integer n, 0 <= n <= 10.000
Output:
A single line with the integer fib(n).
Example:
Input: 10
Output: 55
'''
My raw attempt so to speak:
def fib(n):
if n <= 1:
return n
if n >= 2:
return fib(n-1) + fib(n-2)
n = int(input()) # Read integer n from standard input
print(fib(n))
However this code can only handle up to around n = 500 before reaching maximum recursion depth. To increase that number and create code that can handle up to 10 000, I have tried two things: 1) To increase maximum recursion depth and 2) To use memoization in the form of a decorator. Now the code can handle up to about n = 2000:
import sys
from functools import lru_cache
sys.setrecursionlimit(10000)
#lru_cache(maxsize=None)
def fib(n):
if n <= 1:
return n
if n >= 2:
return fib(n-1) + fib(n-2)
n = int(input()) # Read integer n from standard input
print(fib(n))
With n > 2000 I get an memory error (stack overflow). How do I fix this? What more can I do? Is it even possible with my recursive function or do I have to change it in some way to make it work? Any help is appreciated!
A simple implementation of the nth Fibonacci number. There is no need to use recursion.
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
fa, fb = 0, 1
for i in range(2, n + 1):
fa, fb = fb, fa + fb
return fb
(Note: this is not the fastest. It is O(n). An O(log n) solution is available -- e.g. here, see their method 5.)
With a recursive implementation, you will almost end up with trouble when trying to go to such great depths. Like #alaniwi stated, you can always implement it in a non-recursive method. Here's a O(n) time solution with a O(1) space complexity. (Note: Theoretically you can even get a O(log n) solution.)
from collections import deque
def fib(n):
past = deque([1], maxlen=2)
for _ in range(n): past.appendleft(sum(past))
return past[0]
Because the fibonacci function only requires the last two values of f, we can store only those and bubble upwards.
In the task they give a recursive definition of the fibonacci sequence but nothing is said about a recursive implementation.
This is an iterative implementation of the recursive definition:
def fib(n):
if n == 0:
return 0
f1, f2 = 0, 1
for i in range(1, n + 1):
f1, f2 = f2, f1 + f2
return f2

why maximum recursion limit error is caused when code(1) is executed and no error when code(2) is executed

So here is the 2 python codes of Fibonacci series using recursive function. I wanted to know the difference between these code and why code(1) is not working, and code(2) works without any error?
This is not working and shows error of maximum recursion limit:
def f(n):
return f(n-1) + f(n-2)
n=8
f(n)
whereas this works:
def f(n):
if n == 0:
return 0
if n == 1:
return 1
else:
return f(n-1) + f(n-2)
f(4)
Your first code has no way of stopping. It does not have the base cases for n == 0 or n == 1, so it will continue infinitely downwards with negative numbers.
If you add:
if n <= 1:
return 0
you're golden. (allthough it is a very inefficient implementation of fibonacci).
Why is it inefficient, well because each subtree are calculated many times over. f(8) calls f(7) and f(6), but f(7) also call f(6), so you get an exponential recursive tree. Your running time will be O(2^n). This is really bad, normally you will not be able to calculate fib for n even as low as 50.
You can do better if you include memoization:
from functools import lru_cache
#lru_cache(maxsize=None)
def fib2(n):
if n <= 1:
return n
else:
return fib2(n-1) + fib2(n-2)
This will remember if you have called f(n) before and return the answer you did last time. The issue now is that you need to remember previous called numbers, so while your running time has decreased to O(n), your space requirement is now O(n) too.
You can improve on this again, by abandoning recursive functions all together and go
def fib3(n):
if n == 0:
return 0
f1 = 0
f2 = 1
for i in range(n-1):
f1,f2 = f2, f1+f2
return f2
This is better, since you are only remembering two numbers at any time.

power arguments in Python

Undertaking a task to Write a function power that accepts two arguments, a and b and calculates a raised to the power b.
Example
power(2, 3) => 8
Note: Don't use
2 ** 3
and don't use
Math.pow(2, 3)
I have tried this
def power(a,b):
return eval(((str(a)+"*")*b)[:-1])
And it works but seems to fail one test which is to return_1_when_exp_is_0
and i also get the error
Unhandled Exception: unexpected EOF while parsing (, line 0)
Please how do i solve this issue considering that i am new to python
This worked fine
def power(a,b):
if b == 0:
return 1
else:
return eval(((str(a)+"*")*b)[:-1])
Using eval is a terrible idea, but if you really wanted to then using join() would be a better way to create the string:
def power(a, b):
return eval('*'.join([str(a)]*b))
>>> power(2, 3)
8
If you add ['1'] to the front then the 0 exponent behaves properly:
def power(a, b):
return eval('*'.join(['1']+[str(a)]*b))
>>> power(2, 0)
1
However, this is simple to implement for integer exponents with a for loop:
def power(n, e):
t = 1
for _ in range(e):
t *= n
return t
>>> power(2, 3)
8
>>> power(2, 0)
1
You could also use functools.reduce() to do the same thing:
import functools as ft
import operator as op
def power(n, e):
return ft.reduce(op.mul, [n]*e, 1)
You can use a for loop
x=1
for i in range(b):
x=x*a
print(x)
def power(theNumber, thePower):
#basically, multiply the number for power times
try:
theNumber=int(theNumber)
thePower=int(thePower)
if theNumber == 0:
return 0
elif thePower == 0:
return 1
else:
return theNumber * power(theNumber,thePower-1)
except exception as err:
return 'Only digits are allowed as input'
You should avoid eval by all costs, especially when it's very simple to implement pure algorithmic efficient solution. Classic efficient algorithm is Exponentiation_by_squaring. Instead of computing and multiplying numbers n times, you can always divide it to squares to archive logarithmic* complexity.
For example, for calculating x^15:
x^15 = (x^7)*(x^7)*x
x^7 = (x^3)*(x^3)*x
x^3 = x*x*x
Thus taking 6 multiplications instead of 14.
def pow3(x, n):
r = 1
while n:
if n % 2 == 1:
r *= x
n -= 1
x *= x
n /= 2
return r
Source: https://helloacm.com/exponentiation-by-squaring/
Note: it was not mentioned in the question, but everything above considers N to be positive integer. If your question was also covering fractional or negative exponent, suggested approach will not work "as is".
* Of course depends on length of x and complexity of multiplying, see Wikipedia for detailed complexity analysis.
Also may be interesting to check out following questions: C solution or Python implementing pow() for exponentiation by squaring for very large integers
def power(a, b):
if b == 0:
return 1
else:
return a ** b

python syntax: how to return 0 instead of False when evaluating 0

For an assignment we were asked to define a fibonacci function, which I accomplished with this:
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
However, I have seen recursive functions, such as the factorial function, defined in a one line return statement like so:
def factorial(n):
return n > 1 and n * factorial(n-1) or 1
So, I attempted to apply the same to my fibonacci function. After several attempts, I got it to work for all tested cases except when s = 0, in which case it returns False when it should return 0. Here is where I am:
def fibonacci(n):
return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
I understand that python evaluates 0 to False, so how would I have python return zero instead of False when n is 0 while maintaining the current length/structure of the code? Is that even possible?
Also, is this style of creating a function (recursive or otherwise) more or less desirable/pythonic than the textbook version? (I would imagine not just because of readability)
To be clear, I have satisfied the requirements for the assignment, and for personal knowledge only, I would like a clearer understanding of what is happening in the return statement.
The x and y or z idiom doesn't work if y is falsy. You can swap the condition to make it work nonetheless:
def fibonacci(n):
return n >= 2 and fibonacci(n-1) + fibonacci(n-2) or n
However, as of Python 2.5 (released 6 years ago), we have proper conditional expressions and don't need the and/or hack any longer:
def fibonacci(n):
return n if n < 2 else fibonacci(n-1) + fibonacci(n-2)
Now this has an exponential runtime complexity. If you want to be efficient, use the O(n) algorithm:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
Or even write a generator to yield all the numbers and only take as much as you need.
Perhaps this makes it clearer:
def fibonacci(n):
print ((n == 0 or n == 1) and n)
print (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
print 0 or False
print False or 0

Categories

Resources