Вычисление суммы цифр числа с помощью Python

Раздел: Задачи на числа -> Арифметические операции с цифрами

Введение

Задача нахождения суммы цифр целого числа - одна из базовых в программировании. Её решение демонстрирует работу с циклами, строковыми операциями, рекурсией и функциями высшего порядка. Рассмотрим несколько подходов, от самого эффективного до альтернативных, и разберём возможные проблемы.

Как получить сумму цифр без преобразования в строку?

Наиболее производительный способ - использовать целочисленное деление и взятие остатка. Алгоритм последовательно извлекает последнюю цифру числа по модулю 10, добавляет её к сумме и отбрасывает эту цифру, деля число на 10 нацело. Цикл продолжается, пока число не станет нулевым.


def sum_digits_base(n):
    n = abs(n)  # учитываем отрицательные числа
    total = 0
    while n > 0:
        total += n % 10
        n //= 10
    return total

print(sum_digits_base(12345))  # 15
print(sum_digits_base(-987))   # 24

Python сумма чисел числа (сумма цифр числа в python)

15
24

Такой подход работает только с целыми числами, не требует дополнительной памяти под строку и выполняется за O(log₁₀(n)) операций.

Типичные ошибки и решения:

  • Забыть обработать отрицательное число - берём abs().
  • Не учитывать ноль: для числа 0 цикл не выполнится, сумма останется 0 - это корректно, но можно явно вернуть 0.
  • Модификация исходного числа - если нужно сохранить исходное значение, работаем с копией.

Альтернативные решения

Как использовать строковые операции для нахождения суммы цифр?

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


def sum_digits_str(n):
    return sum(int(d) for d in str(abs(n)))

print(sum_digits_str(2024))  # 8
8

Когда применять:

Когда важна краткость кода, а производительность не критична. Удобно для небольших чисел или одноразовых скриптов.

Проблемы:

  • Создаёт строку и итератор, что при очень больших числах может быть медленнее арифметического способа.
  • Необходимо учитывать знак - вызов abs().

Как применить map и sum для суммирования цифр?

Функция map преобразует каждый символ строки в int, а sum суммирует результаты. Это ещё более компактная запись.


def sum_digits_map(n):
    return sum(map(int, str(abs(n))))

print(sum_digits_map(456))  # 15
15

Подходит для функционального стиля, но имеет те же ограничения по памяти, что и строковый вариант.

Как реализовать рекурсивную функцию для суммы цифр?

Базовый случай: если число меньше 10, возвращаем его. Иначе берём последнюю цифру и прибавляем результат рекурсии для числа без последней цифры.


def sum_digits_recursive(n):
    n = abs(n)
    if n < 10:
        return n
    return n % 10 + sum_digits_recursive(n // 10)

print(sum_digits_recursive(999))  # 27
27

Цели использования:

Демонстрация рекурсии в учебных целях. На практике рекурсия может быть медленнее итерации и ограничена глубиной стека (для Python по умолчанию ~1000 уровней).

Ошибки:

  • Рекурсия без учёта знака - добавляем abs().
  • Для очень больших чисел (например, 10^1000) вызовет переполнение стека.

Как использовать reduce для суммирования цифр?

Функция reduce из модуля functools последовательно применяет функцию к элементам. Для строки цифр можно аккумулировать сумму.


from functools import reduce

def sum_digits_reduce(n):
    return reduce(lambda acc, d: acc + int(d), str(abs(n)), 0)

print(sum_digits_reduce(1357))  # 16
16

Этот вариант чаще всего избыточен, но может быть полезен в цепочках функциональных преобразований.

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

В большинстве задач под «суммой цифр» понимают сумму абсолютных значений цифр, игнорируя знак. Если же требуется учесть знак (например, для -123 сумма = -1-2-3 = -6), то необходимо модифицировать алгоритм.


def sum_digits_signed(n):
    sign = -1 if n < 0 else 1
    n = abs(n)
    total = 0
    while n > 0:
        total += n % 10
        n //= 10
    return total * sign

print(sum_digits_signed(-123))  # -6
-6

Внимание:

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

Как обработать дробные числа?

Если число с плавающей точкой, можно взять целую часть (int(n)) или обрабатывать цифры после запятой отдельно. Чаще всего задача ставится для целых чисел.


def sum_digits_float(n):
    # рассматриваем только целую часть
    return sum_digits_base(int(abs(n)))

print(sum_digits_float(34.7))  # 7 (3+4)
7

Для учёта дробной части потребуется преобразование в строку с разбиением по точке.

Расширенные примеры и неочевидные сценарии

Сумма цифр для отрицательных чисел с сохранением знака

Иногда требуется сумма цифр с учётом знака самого числа. Реализация с использованием divmod:

Пример

def sum_digits_signed_divmod(n):
    sign = 1 if n >= 0 else -1
    n = abs(n)
    total = 0
    while n:
        n, digit = divmod(n, 10)
        total += digit
    return total * sign

print(sum_digits_signed_divmod(-456))  # -15
print(sum_digits_signed_divmod(789))   # 24
-15
24

Цифровой корень (сумма цифр до одной цифры)

Итеративное суммирование цифр числа до получения однозначного результата. Можно реализовать без циклов через формулу: dr = 1 + (n-1) % 9 для n>0 (кроме 0). Но покажем итеративный способ:

Пример

def digital_root_iter(n):
    n = abs(n)
    while n >= 10:
        n = sum(int(d) for d in str(n))
    return n

print(digital_root_iter(98765))  # 9+8+7+6+5=35 → 3+5=8
8

Сумма цифр для списка чисел

Применяем одну из функций к каждому элементу списка с помощью map:

Пример

def sum_digits_list(numbers):
    return list(map(sum_digits_base, numbers))

nums = [123, -456, 7890, 0]
print(sum_digits_list(nums))  # [6, 15, 24, 0]
[6, 15, 24, 0]

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

Используем модуль timeit для замера времени на миллион вызовов для числа 123456789:

Пример

import timeit

num = 123456789
base_time = timeit.timeit(lambda: sum_digits_base(num), number=1000000)
str_time = timeit.timeit(lambda: sum_digits_str(num), number=1000000)
map_time = timeit.timeit(lambda: sum_digits_map(num), number=1000000)
rec_time = timeit.timeit(lambda: sum_digits_recursive(num), number=1000000)
print(f"base: {base_time:.4f}")
print(f"str:  {str_time:.4f}")
print(f"map:  {map_time:.4f}")
print(f"rec:  {rec_time:.4f}")
base: 0.4231
str:  1.2145
map:  1.1023
rec:  0.9876

Арифметический метод оказывается самым быстрым. Рекурсия хоть и близка по скорости, но может быть ограничена глубиной.

Сумма цифр числа в другой системе счисления

Если нужно найти сумму цифр числа, записанного, например, в двоичной системе, то основание меняется. Адаптируем базовый алгоритм:

Пример

def sum_digits_base_n(num, base=10):
    num = abs(num)
    total = 0
    while num > 0:
        total += num % base
        num //= base
    return total

# Для двоичного представления числа 13 (1101) сумма цифр = 1+1+0+1=3
print(sum_digits_base_n(13, 2))   # 3
# Для шестнадцатеричного: 255 (FF) -> 15+15=30
print(sum_digits_base_n(255, 16)) # 30
3
30

Сумма цифр числа в Python - comments

En
Python сумма чисел числа (python)