Преобразование цифр в словесную форму: методы Python

Раздел: Строки -> Форматирование вывода

Преобразование чисел в текст на Python

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

Как быстро преобразовать число в текст на русском языке с помощью готовой библиотеки?

Самый простой и надёжный путь - использовать библиотеку num2words. Она поддерживает множество языков, включая русский, и правильно обрабатывает склонения, роды и большие числа (до 10^66). Установка через pip:

pip install num2words

ввод через пробел python (ввод и вывод чисел через пробел в python)

Пример использования:

from num2words import num2words
print(num2words(12345, lang='ru'))

вывод через пробел python (вывод через пробел в python)

двенадцать тысяч триста сорок пять

Python print sep (параметр sep в print python)

Функция num2words принимает число и параметр lang. Дополнительно можно указать to='currency' для денежных сумм, ordinal=True для порядковых числительных.

Возможные проблемы

  • Неверный регистр: библиотека выводит текст в нижнем регистре. Если требуется заглавная буква в начале строки, нужно применить capitalize().
  • Отсутствие поддержки некоторых валют: для денежного формата нужно указать код валюты (например, currency='RUB').
  • Большие числа могут быть обработаны, но при длине более 66 разрядов (секстиллионов) возникнет ошибка.

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

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

def число_прописью(число):
    единицы = ['', 'один', 'два', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять']
    десятки = ['', 'десять', 'двадцать', 'тридцать', 'сорок', 'пятьдесят', 'шестьдесят', 'семьдесят', 'восемьдесят', 'девяносто']
    сотни = ['', 'сто', 'двести', 'триста', 'четыреста', 'пятьсот', 'шестьсот', 'семьсот', 'восемьсот', 'девятьсот']
    # ... полное определение словарей опущено для краткости
    return результат

Python форматирование чисел (форматирование чисел при выводе в python)

Подробная реализация потребует учёта склонений (например, для тысяч: 'тысяча', 'тысячи', 'тысяч') и особых форм для чисел 10-19. Ошибки часто возникают из-за неверного согласования родов и чисел (например, 'два рубля' vs 'две тысячи').

Типичные ошибки ручной реализации

  • Пропуск слова для нулевого разряда.
  • Неправильное склонение тысяч: 'одна тысяча' (женский род) для 1, но 'две тысячи' для 2.
  • Некорректное формирование чисел от 11 до 19: они должны использовать особые формы ('одиннадцать', 'двенадцать'...).

Как учесть падежи и роды при выводе числа прописью с помощью pymorphy2?

Библиотека pymorphy2 предназначена для морфологического анализа русских слов. Её можно использовать для склонения числительных в нужный падеж (родительный, дательный и т.д.). Например, требуется вывести число в родительном падеже: 'пятьсот рублей' -> 'пятисот рублей'.

import pymorphy2
morph = pymorphy2.MorphAnalyzer()

# преобразование числа в пропись (через num2words) и затем склонение
from num2words import num2words
text = num2words(500, lang='ru')
# разбиваем на слова и склоняем каждое
words = text.split()
inflected = [morph.parse(w)[0].inflect({'gent'}).word for w in words]
print(' '.join(inflected))

формат вывода строки python (формат вывода строки в python)

пятисот

список без скобок python (вывод списка без скобок в python)

Этот подход более гибкий, но требует дополнительной обработки (выбор правильной парадигмы для каждого слова). Основная проблема - числительные могут быть не распознаны pymorphy2 как одно слово, например 'двадцать' будет разобрано, а 'двадцать один' - как два слова. Рекомендуется склонять только числительные, а существительные (рубли, копейки) - отдельно.

Проблемы с pymorphy2

  • Нужно загрузить словарь (примерно 10–20 МБ).
  • Склонение составных числительных (от 21 и выше) может требовать разбора каждого компонента.
  • Производительность ниже, чем у num2words.

Как вывести число как денежную сумму прописью с указанием валюты?

Библиотека num2words поддерживает режим currency. Пример:

from num2words import num2words
print(num2words(1234.56, lang='ru', to='currency', currency='RUB'))

Python число вывести текстом (вывод числа прописью в python)

одна тысяча двести тридцать четыре рубля пятьдесят шесть копеек

Для сумм с копейками дробная часть обрабатывается автоматически. Если нужно вывести только целую часть, используйте to='currency' с округлением.

Для других валют измените параметр currency: 'USD', 'EUR', 'KZT' и т.д. Поддержка валют зависит от версии библиотеки.

Возможные сложности

  • Не все валюты имеют корректные формы множественного числа (например, 'долларов' vs 'доллара'). Проверьте перед использованием.
  • Суммы с нулевой копеечной частью могут отображаться как 'ноль копеек'.

Расширенные примеры преобразования чисел в текст

1. Использование num2words с разными настройками

Порядковые числительные:

Пример
from num2words import num2words
print(num2words(21, lang='ru', ordinal=True))
двадцать первый

Число с дробной частью (не денежный режим):

Пример
print(num2words(3.14, lang='ru'))
три целых четырнадцать сотых

Большое число:

Пример
print(num2words(10**15, lang='ru'))
один квадриллион

2. Ручная функция с учётом падежа (только для тысяч в родительном)

Пример
def число_в_родительном(число):
    from num2words import num2words
    import pymorphy2
    morph = pymorphy2.MorphAnalyzer()
    text = num2words(число, lang='ru')
    words = []
    for word in text.split():
        parsed = morph.parse(word)[0]
        # Если слово может быть числительным, склоняем в родительный
        if 'NUMR' in parsed.tag:
            inf = parsed.inflect({'gent'})
            words.append(inf.word if inf else word)
        else:
            words.append(word)
    return ' '.join(words)

print(число_в_родительном(567))
пятисот шестидесяти семи

Примечание: функция простая и может дать неверный результат для составных числительных (21 -> 'двадцати одного'? на самом деле 'двадцати одного'). В реальных проектах лучше использовать готовые решения.

3. Преобразование числа с ведущими нулями (строковый аргумент)

Если число передано как строка с ведущими нулями, например '00123', нужно сначала преобразовать в int, чтобы удалить нули:

Пример
from num2words import num2words
s = '00123'
число = int(s)
print(num2words(число, lang='ru'))
сто двадцать три

4. Отрицательные числа и ноль

Пример
print(num2words(-10, lang='ru'))
print(num2words(0, lang='ru'))
минус десять
ноль

5. Денежный формат с разными валютами

Пример
print(num2words(999.99, lang='ru', to='currency', currency='USD'))
print(num2words(1000, lang='ru', to='currency', currency='EUR', cents=False))
девятьсот девяносто девять долларов девяносто девять центов
одна тысяча евро

Параметр cents=False отключает вывод копеек/центов.

6. Сравнение производительности разных методов (для 10 000 итераций)

Пример
import timeit

# num2words
setup = 'from num2words import num2words
test = 123456789'
time1 = timeit.timeit('num2words(test, lang="ru")', setup=setup, number=10000)

# pymorphy2 + num2words (только склонение)
setup2 = '''from num2words import num2words
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
test = 123456789
'''
time2 = timeit.timeit('''
text = num2words(test, lang="ru")
' '.join(morph.parse(w)[0].inflect({"gent"}).word for w in text.split())
''', setup=setup2, number=10000)

print(f'num2words: {time1:.3f}s')
print(f'num2words + pymorphy2: {time2:.3f}s')
num2words: 1.245s
num2words + pymorphy2: 12.876s

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

Вывод числа прописью в Python - comments

En
Python число вывести текстом (python)