Back to Data Structures & Algorithms
2026-03-118 min read

Python Program to Find Factorial of Number Using Recursion (Data Structures & Algorithms)

Learn Python Program to Find Factorial of Number Using Recursion (Data Structures & Algorithms) step by step with clear examples and exercises.

Why This Matters

The ability to calculate factorials is an essential skill for any programmer as they are fundamental in various mathematical and computational problems. Factorials are used often in algorithms for permutations, combinations, and probabilities. Understanding how to calculate factorials using recursion helps solve complex problems more efficiently. Additionally, being able to write such programs can be beneficial during job interviews or competitive programming contests.

Importance of Recursion in Factorial Calculation

Recursion is a powerful technique that allows us to break down complex problems into smaller, manageable sub-problems. In the case of factorials, recursion provides a simple and elegant solution for calculating large factorials. Recursive functions can be easier to understand and maintain compared to iterative solutions, especially for more complex problems.

Prerequisites

To understand this lesson, you should have a good grasp of the following Python concepts:

  1. Basic Python syntax
  2. Control structures (if-else statements and loops)
  3. Function definitions and recursion
  4. Understanding of Big O notation to analyze the time complexity of algorithms
  5. Familiarity with common data structures like lists and arrays
  6. Concepts of memoization and tail recursion (for optimization)

Core Concept

Understanding Factorials

The factorial of a non-negative integer n is the product of all positive integers up to n. It is denoted by n!, where the exclamation mark indicates that the factorial operation has been applied. For example, the factorial of 5 (written as 5!) is calculated as follows:

5! = 5 * 4 * 3 * 2 * 1 = 120

Factorial using Recursion

We can write a recursive function in Python to calculate the factorial of a given number. The base case is when n equals 1, and the function returns 1. For any other value of n, it calls itself with n-1 as an argument and multiplies the result by n.

def recur_factorial(n):
if n == 1:
return 1
else:
return n * recur_factorial(n - 1)

Big O Notation Analysis

The time complexity of the recursive factorial function is O(n), as it performs n multiplication operations. However, due to the overhead of recursion, its practical performance can be much worse for large values of n.

Iterative Approach

An iterative approach using loops can also be used to calculate factorials with better efficiency than the recursive method for larger numbers:

def iter_factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result

Memoization and Tail Recursion Optimizations

To improve the performance of recursive factorial functions, particularly for large values of n, we can use memoization or tail recursion. These techniques help reduce redundant calculations and optimize the code's efficiency.

Memoization

Memoization is a technique used to store previously calculated results in a cache or dictionary to avoid redundant calculations. This approach can significantly improve the performance of recursive functions by reducing the number of function calls.

def memoized_factorial(n, memo={}):
if n in memo:
return memo[n]
elif n < 0:
print("Error: Factorial not defined for negative numbers.")
return None
elif n == 1:
result = 1
else:
result = n * memoized_factorial(n - 1, memo)
memo[n] = result
return result

Tail Recursion

Tail recursion is a specific type of recursive function where the last operation is a recursive call, allowing compilers to optimize the code by converting it into an iterative loop. This optimization can help reduce the overhead associated with multiple function calls and improve performance.

def tail_recursive_factorial(n, result=1):
if n == 1:
return result
else:
return tail_recursive_factorial(n - 1, result * n)

Worked Example

Let's calculate the factorial of 7 using our recursive and iterative functions, as well as the memoized and tail-recursive optimized versions.

def recur_factorial(n):
if n == 1:
return 1
else:
return n * recur_factorial(n - 1)

def iter_factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result

def memoized_factorial(n, memo={}):
if n in memo:
return memo[n]
elif n < 0:
print("Error: Factorial not defined for negative numbers.")
return None
elif n == 1:
result = 1
else:
result = n * memoized_factorial(n - 1, memo)
memo[n] = result
return result

def tail_recursive_factorial(n, result=1):
if n == 1:
return result
else:
return tail_recursive_factorial(n - 1, result * n)

num = 7
result_recur = recur_factorial(num)
result_iter = iter_factorial(num)
result_memo = memoized_factorial(num)
result_tail = tail_recursive_factorial(num)
print("The factorial of", num, "using recursion is", result_recur)
print("The factorial of", num, "using iteration is", result_iter)
print("The factorial of", num, "using memoization is", result_memo)
print("The factorial of", num, "using tail recursion is", result_tail)

When you run this code, it will output:

The factorial of 7 using recursion is 5040
The factorial of 7 using iteration is 5040
The factorial of 7 using memoization is 5040
The factorial of 7 using tail recursion is 5040

How It Works Internally

When we call recur_factorial(7), the function is first evaluated for n=7. Since n does not equal 1, it calls itself with n-1 (i.e., 6) as an argument and multiplies the result by 7. This process repeats until the base case n=1 is reached, at which point the function returns 1. The recursive calls are then combined to produce the final result:

recur_factorial(7) = 7 * recur_factorial(6)
= 7 * (6 * recur_factorial(5))
= 7 * (6 * (5 * recur_factorial(4)))
= 7 * 6 * (5 * (4 * recur_factorial(3)))
= 7 * 6 * 5 * (4 * (3 * recur_factorial(2)))
= 7 * 6 * 5 * 4 * (2 * recur_factorial(1))
= 7 * 6 * 5 * 4 * 2 * (1 * recur_factorial(0))
= 7 * 6 * 5 * 4 * 2 * 1 * 0

Since the factorial of 0 is defined as 1, the final result is:

recur_factorial(7) = 7 * 6 * 5 * 4 * 2 * 1 * 1 = 5040

The iterative approach calculates the factorial by looping through each number from 2 to n, multiplying them together, and storing the result in a variable. Memoization stores previously calculated results in a cache or dictionary, while tail recursion optimizes the code by converting it into an iterative loop.

Common Mistakes

  1. Negative Input: The factorial function only works for non-negative integers. If a negative number is passed, the program will raise an error. To handle both positive and negative numbers, you can use conditional statements to check if the input is negative before calculating the factorial.
def factorial(n):
if n < 0:
print("Error: Factorial not defined for negative numbers.")
return None
elif n == 0:
return 1
else:
result = 1
for i in range(2, n + 1):
result *= i
return result
  1. Recursion Depth Limit: If the recursive calls exceed Python's maximum recursion depth, the program will crash with a RecursionError. To avoid this, you can increase the recursion limit using the sys module:
import sys
sys.setrecursionlimit(10000) # Set the recursion limit to 10,000

def factorial(n):
if n < 0:
print("Error: Factorial not defined for negative numbers.")
return None
elif n == 0:
return 1
else:
return n * factorial(n - 1)
  1. Inefficient Recursive Implementation: The recursive implementation can be optimized by using memoization or tail recursion to avoid redundant calculations and improve performance for large numbers.

Practice Questions

  1. Write a recursive function to calculate the sum of the first n natural numbers (1, 2, 3, ..., n).
  2. Modify the factorial function to handle both positive and negative integers using iterative approach.
  3. Write a recursive function to find the Fibonacci sequence up to n terms.
  4. Implement an optimized recursive implementation of the factorial function using memoization or tail recursion.
  5. Compare the time complexity and practical performance of the recursive, iterative, and optimized recursive implementations for large values of n.
  6. Write a recursive function to find the greatest common divisor (GCD) of two numbers using Euclid's algorithm.
  7. Implement an iterative version of the GCD function using loops.
  8. Compare the time complexity and practical performance of the recursive and iterative GCD implementations for large values of the input numbers.
  9. Write a recursive function to calculate the power of a number a raised to the power b.
  10. Implement an iterative version of the power function using loops.
  11. Compare the time complexity and practical performance of the recursive and iterative power implementations for large values of a and b.

FAQ

  1. Why does the recursive factorial function take longer to compute larger numbers?

Recursion involves multiple function calls, each with its own overhead. As the number increases, more calls are required, which can lead to slower performance compared to iterative methods that use loops. Additionally, the recursive method has a time complexity of O(n), while the iterative approach has a time complexity of O(n).

  1. What is the Big O notation for the recursive factorial function?

The time complexity of the recursive factorial function is O(n), as it performs n multiplication operations. However, due to the overhead of recursion, its practical performance can be much worse for large values of n.

  1. Why does Python have a maximum recursion depth limit?

The maximum recursion depth limit exists to prevent infinite loops and stack overflows that could potentially crash the interpreter or consume excessive memory. By default, Python sets this limit to 1024, but it can be increased using the sys.setrecursionlimit() function.

  1. What are memoization and tail recursion?

Memoization is a technique used to store previously calculated results in a cache or dictionary to avoid redundant calculations. Tail recursion is a specific type of recursive function where the last operation is a recursive call, allowing compilers to optimize the code by converting it into an iterative loop.

  1. How can I implement memoization for the factorial function?

To implement memoization for the factorial function, create a dictionary to store previously calculated results and check if the result is already in the cache before performing the calculation:

def memoized_factorial(n, memo={}):
if n in memo:
return memo[n]
elif n < 0:
print("Error: Factorial not defined for negative numbers.")
return None
elif n == 1:
result = 1
else:
Python Program to Find Factorial of Number Using Recursion (Data Structures & Algorithms) | Data Structures & Algorithms | XQA Learn