Factorial of a Number in Python

As a software engineer who has worked with Python for many years across the USA, I’ve implemented factorial calculations more times than I can count. In this comprehensive guide, I’ll walk you through multiple approaches to calculating the factorial of a number in Python, from the simplest implementations to highly optimized solutions.

What is a Factorial?

Before getting into the code, let’s quickly refresh what a factorial is. The factorial of a non-negative integer n, denoted as n! is the product of all positive integers less than or equal to n.

Mathematically, it’s defined as:

  • n! = n × (n-1) × (n-2) × … × 3 × 2 × 1
  • 0! is defined as 1

Now, let’s explore the various ways to implement factorial calculations in Python.

Read Happy Birthday Code in Python

Method 1: Use Iterative Approach

The most simple way to calculate a factorial is using a loop:

def factorial_iterative(n):
    """Calculate factorial using iteration."""
    if n < 0:
        raise ValueError("Factorial is not defined for negative numbers")

    result = 1
    for i in range(1, n + 1):
        result *= i

    return result

# Example usage
number = 5
print(f"The factorial of {number} is: {factorial_iterative(number)}")  

Output:

The factorial of 5 is: 120

You can see the output in the screenshot below.

factorial of a number in python

This approach is: easy to understand, memory efficient (O(1) space complexity), and suitable for smaller numbers.

Check out Download and Extract ZIP Files from a URL Using Python

Method 2: Use Recursion

Recursion provides an efficient way to calculate factorials that mirrors the mathematical definition:

def factorial_recursive(n):
    """Calculate factorial using recursion."""
    if n < 0:
        raise ValueError("Factorial is not defined for negative numbers")

    # Base case
    if n == 0 or n == 1:
        return 1

    # Recursive case
    return n * factorial_recursive(n - 1)

# Example usage
number = 6
print(f"The factorial of {number} is: {factorial_recursive(number)}")

Output:

The factorial of 6 is: 720

You can see the output in the screenshot below.

factorial of a number

While beautiful in its simplicity, be aware that: Python has a default recursion depth limit (typically 1000), This approach consumes more memory due to the call stack (O(n) space complexity), It may cause a stack overflow for large numbers.

Read How to Save Images in Python?

Method 3: Use the math.factorial Function

Python’s standard library includes a factorial function in the math module:

import math

# Example usage
number = 7
result = math.factorial(number)
print(f"The factorial of {number} is: {result}") 

Output:

The factorial of 7 is: 5040

You can see the output in the screenshot below.

python factorial

This implementation is: Highly optimized (written in C), The most recommended approach for production code, and Handles edge cases gracefully.

Check out How to Print Prime Numbers from 1 to N in Python?

Method 4: Use reduce() Function

The reduce() function from the functools module offers a functional programming approach:

from functools import reduce
import operator

def factorial_reduce(n):
    """Calculate factorial using reduce() function."""
    if n < 0:
        raise ValueError("Factorial is not defined for negative numbers")
    if n == 0:
        return 1

    return reduce(operator.mul, range(1, n + 1))

# Example usage
number = 8
print(f"The factorial of {number} is: {factorial_reduce(number)}") 

Output:

The factorial of 8 is: 40320

You can see the output in the screenshot below.

factorial in python

This approach: Is concise and elegant, Shows your familiarity with functional programming concepts, and Performs reasonably well for most use cases.

Read Python Program to Print Prime Numbers from 1 to 100

Method 5: Use Tail Recursion Optimization

While Python doesn’t natively optimize tail recursion, we can implement it manually:

def factorial_tail_recursive(n, accumulator=1):
    """Calculate factorial using tail recursion optimization."""
    if n < 0:
        raise ValueError("Factorial is not defined for negative numbers")

    # Base case
    if n == 0:
        return accumulator

    # Recursive case with accumulator
    return factorial_tail_recursive(n - 1, n * accumulator)

# Example usage
number = 9
print(f"The factorial of {number} is: {factorial_tail_recursive(number)}")  # Output: 362880

I learned this technique during my computer science studies at Stanford and have used it when working on projects requiring both readability and efficiency.

Check out How to Find Prime Numbers in a Range Using Python?

Method 6: Use Dynamic Programming for Large Factorials

For very large numbers, we can use dynamic programming to memoize results:

def factorial_dynamic(n, memo={}):
    """Calculate factorial using dynamic programming."""
    if n < 0:
        raise ValueError("Factorial is not defined for negative numbers")

    if n in memo:
        return memo[n]

    if n == 0 or n == 1:
        return 1

    memo[n] = n * factorial_dynamic(n - 1, memo)
    return memo[n]

# Example usage
number = 10
print(f"The factorial of {number} is: {factorial_dynamic(number)}")  # Output: 3628800

This approach: Avoids redundant calculations, Can significantly improve performance for repeated calculations, and Uses more memory to store previously computed results.

Read How to Find the Next Largest Prime Number in Python?

Method 7: Use Lambda Functions

To the users who like concise code, we can define a factorial using a lambda function:

factorial_lambda = lambda n: 1 if n <= 1 else n * factorial_lambda(n - 1)

# Example usage
number = 4
print(f"The factorial of {number} is: {factorial_lambda(number)}")  # Output: 24

While this approach is succinct, I generally advise my team at our Seattle-based startup to avoid recursive lambda functions in production code due to readability concerns.

Check out How to Generate a Random Prime Number in Python?

Method 8: Use the math.prod Function

If you’re using Python 3.8 or newer, you can use the math.prod function:

import math

def factorial_prod(n):
    """Calculate factorial using math.prod (Python 3.8+)."""
    if n < 0:
        raise ValueError("Factorial is not defined for negative numbers")
    if n == 0:
        return 1

    return math.prod(range(1, n + 1))

# Example usage
number = 5
print(f"The factorial of {number} is: {factorial_prod(number)}")  # Output: 120

This is one of my favorite approaches when working with newer Python versions due to its clarity and performance.

Read How to Use Constructors in Python?

Applications of Factorials in Python

Let me share some real-world scenarios where I’ve implemented factorial calculations:

1. Combinatorics and Probability

To calculate the number of possible ways to arrange n distinct objects (permutations):

def permutations(n, r):
    """Calculate nPr (permutations)."""
    return math.factorial(n) // math.factorial(n - r)

# How many ways can we select and arrange 3 books from a shelf of 10?
print(permutations(10, 3))  # Output: 720

2. Statistics and Data Science

For calculating combinations (often used in probability and statistics):

def combinations(n, r):
    """Calculate nCr (combinations)."""
    return math.factorial(n) // (math.factorial(r) * math.factorial(n - r))

# In how many ways can we select a committee of 4 people from a group of 12?
print(combinations(12, 4))  # Output: 495

During my work with a healthcare analytics firm in Minneapolis, we used combinations extensively to analyze patient treatment patterns.

3. Scientific Computing

Factorials are fundamental in Taylor series expansions:

def exp_approximation(x, terms=10):
    """Approximate e^x using Taylor series."""
    result = 0
    for n in range(terms):
        result += (x ** n) / math.factorial(n)
    return result

# Approximate e^1 and compare with math.e
approx = exp_approximation(1, 20)
print(f"Approximation of e: {approx}")
print(f"Actual value of e: {math.e}")
print(f"Difference: {abs(approx - math.e)}")
# Output shows a very small difference

Check out How to Implement Constructor Overloading in Python?

Best Practices

After years of writing Python code across different industries, here are my recommendations:

  • For everyday use: Use math.factorial() – it’s optimized, readable, and handles edge cases
  • For educational purposes: The iterative or recursive approach helps understand the concept better
  • For very large factorials: Use specialized libraries like mpmath
  • For performance-critical code: Benchmark different approaches on your specific use case

Read How to Call Super Constructor in Python?

Conclusion

In this article, I explained the factorial of a number in Python. I discussed some important methods such as using an iterative approach, using recursion, using math.factorial function, using the reduce() function, using tail recursion optimization, using dynamic programming for large factorials, using lambda function, and using math.prod function. I also covered applications and some best practices.

You may read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.