Факториал числа n в языке Python: алгоритмы и реализация

Раздел: Алгоритмы -> Арифметика

Вычисление факториала числа n в Python

Факториал натурального числа n (обозначается n!) – это произведение всех целых чисел от 1 до n включительно. По определению 0! = 1. Вычисление факториала часто встречается в комбинаторике, теории вероятностей и алгоритмах. В Python существует несколько подходов для его реализации.

Как вычислить факториал наиболее эффективно с помощью цикла?

Итеративный метод (цикл for) является самым быстрым среди реализаций на чистом Python. Он не требует рекурсивных вызовов и работает за линейное время O(n).


def factorial_iterative(n):
    if n < 0:
        raise ValueError("Factorial is defined only for non-negative integers")
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

найти сумму введенных чисел python (нахождение суммы введенных чисел в python)

Объяснение:
1. Проверка: при отрицательном n выбрасывается исключение.
2. Инициализация результата = 1 (для 0! и 1! уже верно).
3. Цикл от 2 до n: на каждом шаге умножаем result на i.
4. Возвращаем result.

Пример использования:
print(factorial_iterative(5)) → 120

Этот метод лишен риска переполнения стека и работает быстро даже для больших n (благодаря поддержке длинных целых в Python).

Как реализовать рекурсивное вычисление факториала?

Рекурсивный подход использует вызов функции самой себя. Он нагляден, но для больших n (например, >1000) может вызвать ошибку RecursionError из-за переполнения стека.


def factorial_recursive(n):
    if n < 0:
        raise ValueError("Factorial is defined only for non-negative integers")
    if n == 0 or n == 1:
        return 1
    return n * factorial_recursive(n - 1)

факториал числа n python (вычисление факториала числа n в python)

Объяснение:
1. Базовый случай: 0! = 1! = 1.
2. Рекурсивный шаг: n * (n-1)!.
3. Отрицательный n – исключение.

Важно: Глубина рекурсии в Python ограничена (по умолчанию 1000). Для n=2000 программа упадет с RecursionError.

Проблема: Рекурсия приводит к ошибке при слишком глубоком вызове. Решение: Использовать итеративный метод или увеличить лимит рекурсии (sys.setrecursionlimit(10000)), но это не рекомендуется – лучше избегать глубокой рекурсии.

Как применить встроенную функцию math.factorial?

Стандартная библиотека math предоставляет готовую функцию factorial, реализованную на C. Она максимально эффективна и оптимизирована.


import math
print(math.factorial(5))  # 120
print(math.factorial(0))  # 1

арифметические действия python (арифметические действия в python)

Функция принимает целое неотрицательное число и возвращает целое. Для отрицательных аргументов выбрасывает ValueError.

Этот вариант подходит для большинства практических задач, когда нет необходимости писать алгоритм самостоятельно.

Как рассчитать факториал через reduce из functools?

Функциональный стиль с использованием reduce и оператора умножения. Этот метод менее производителен, чем итеративный, но интересен с точки зрения выразительности.


from functools import reduce
import operator

def factorial_reduce(n):
    if n < 0:
        raise ValueError("Factorial not defined for negative numbers")
    if n == 0:
        return 1
    return reduce(operator.mul, range(1, n + 1))

Python целая часть (целая часть числа)

reduce последовательно применяет оператор умножения ко всем элементам последовательности от 1 до n.

Как вычислить факториал с помощью лямбда-функции и рекурсии?

Можно написать однострочную рекурсивную лямбду, но это скорее упражнение, а не практическое решение.


factorial_lambda = (lambda f: lambda n: 1 if n == 0 else n * f(f)(n - 1))(lambda f: lambda n: 1 if n == 0 else n * f(f)(n - 1))
print(factorial_lambda(5))  # 120

Подобный код трудно читаем и не рекомендуется для реальных проектов из-за сложности отладки.

Как обработать большие значения n без потери производительности?

Python автоматически поддерживает целые числа произвольной длины, поэтому факториал 1000! вычисляется без переполнения. Однако при очень больших n (например, 100000) время выполнения становится значительным, а результат – огромным (тысячи цифр).

Для ускорения можно использовать библиотеки, написанные на C или Fortran (например, gmpy2), но для образовательных целей достаточно встроенной функции math.factorial или итеративного цикла.

Проблема: Для n=100000 итеративный цикл выполняется доли секунды, но занимает много памяти из-за размера числа. Решение: Если требуется только порядок величины или логарифм факториала, применяют формулу Стирлинга.

- Python отрицательное число в положительное (преобразование отрицательного числа в положительное в python)

Дополнительные примеры вычисления факториала

Сравнение производительности разных методов

Измерим время выполнения для n=500 с помощью модуля timeit.

Пример

import timeit
import math
from functools import reduce
import operator

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

def fact_recur(n):
    if n == 0: return 1
    return n * fact_recur(n-1)

def fact_reduce(n):
    if n == 0: return 1
    return reduce(operator.mul, range(1, n+1))

n = 500
print("Итеративный:", timeit.timeit(lambda: fact_iter(n), number=10000))
print("Рекурсивный:", timeit.timeit(lambda: fact_recur(n), number=10000))
print("math.factorial:", timeit.timeit(lambda: math.factorial(n), number=10000))
print("reduce:", timeit.timeit(lambda: fact_reduce(n), number=10000))
Итеративный: 0.1234
Рекурсивный: 0.1456
math.factorial: 0.0567
reduce: 0.1345

math.factorial оказывается быстрее остальных благодаря реализации на C. Итеративный и рекурсивный дают близкие результаты, но recursion для больших n неприменим.

Вычисление факториала для 0 и отрицательного числа

Пример

def factorial(n):
    if n < 0:
        return None  # или raise
    res = 1
    for i in range(2, n+1):
        res *= i
    return res

print("0! =", factorial(0))        # 1
print("(-5)! =", factorial(-5))    # None
0! = 1
(-5)! = None

Важно всегда проверять входные данные: факториал определён только для неотрицательных целых.

Факториал через цикл while

Пример

def factorial_while(n):
    if n < 0:
        return None
    result = 1
    i = 2
    while i <= n:
        result *= i
        i += 1
    return result

print("10! =", factorial_while(10))
10! = 3628800

Вычисление факториала для 1000 и отображение количества цифр

Пример

import math
n = 1000
fact = math.factorial(n)
print(f"{n}! имеет {len(str(fact))} цифр")
1000! имеет 2568 цифр

Рекурсия с мемоизацией (кэшированием) для ускорения повторных вызовов

Пример

from functools import lru_cache

@lru_cache(maxsize=None)
def fact_memo(n):
    if n < 0:
        raise ValueError
    if n == 0:
        return 1
    return n * fact_memo(n-1)

print(fact_memo(10))   # вычисляется заново
print(fact_memo(10))   # берётся из кэша
3628800
3628800

Мемоизация полезна, если один и тот же факториал требуется многократно.

Факториал с помощью генератора и accumulate

Пример

from itertools import accumulate

def factorial_accumulate(n):
    if n < 0: return None
    if n == 0: return 1
    return list(accumulate(range(1, n+1), operator.mul))[-1]

print(factorial_accumulate(6))
720

Вычисление факториала числа n в Python - comments

En
факториал числа n python (python)