Сколько чисел в строке? Варианты подсчёта в Python
Подсчёт чисел: эффективные подходы
Подсчёт чисел в строке - частая задача при обработке текстов, логов, пользовательского ввода. Под числом будем понимать последовательность цифр (целые неотрицательные числа). Если требуются дробные, отрицательные или числа с разделителями - это расширенные случаи, рассмотренные в других вариантах. Далее приведён основной метод и альтернативы с пояснениями.
Как наиболее быстро подсчитать количество целых чисел в строке?
Самый компактный и производительный способ - использовать регулярное выражение \d+, которое находит одну или несколько цифр подряд. Модуль re встроен в Python и оптимизирован для таких операций.
import re
text = "В 2024 году 7 чудес и 12 подвигов"
count = len(re.findall(r'\d+', text))
print(count) # 3заменить символ на другой python (замена символа в строке на python)
Пояснение: re.findall возвращает список всех непересекающихся совпадений. Функция len вычисляет длину списка - количество чисел.
Проблема: если строка содержит числа внутри других слов (например, "abc123def"), такое совпадение будет найдено, что может быть нежелательно. Решение: добавлять границы слова \b - r'\b\d+\b'. Другая проблема - числа с плавающей точкой (3.14) будут распознаны как два отдельных числа (3, 14). Для дробных чисел требуется другой шаблон: r'\d+\.\d+' или r'\d+\.?\d*' - но тогда строка "3" будет найдена как "3" без точки, а "3." - как "3" и пусто. Лучше использовать r'\d+(\.\d+)?'.
Как подсчитать числа без регулярных выражений?
Если по каким‑то причинам нельзя использовать re (например, ограничения среды) или нужно учитывать только числа, отделённые пробелами, подойдёт метод с разделением строки и проверкой каждого токена.
text = "42 ответ 1.5 и -3"
tokens = text.split()
count = sum(1 for token in tokens if token.isdigit())
print(count) # 1 (только "42")Strip строки python (метод strip для строк в python)
Пояснение: str.split() разбивает строку по пробельным символам. Метод isdigit() проверяет, состоят ли все символы токена из цифр. Минус - не распознаёт дробные и отрицательные числа.
Проблема: isdigit() вернёт True для "²" (надстрочный знак) или "۱۲۳" (арабские цифры). Если нужна строгая проверка десятичных цифр 0–9, используйте token.isdecimal() или регулярное выражение. Кроме того, числа в составе сложных строк ("abc123") не будут выделены.
Как посчитать числа, которые могут быть дробными или отрицательными?
Используйте ту же логику разбиения, но с функцией try/except или встроенной проверкой str.replace и isdigit.
def is_number(token):
try:
float(token)
return True
except ValueError:
return False
text = "Температура -3.5 и 7"
count = sum(1 for token in text.split() if is_number(token))
print(count) # 2
сколько чисел в строке python (подсчёт количества чисел в строке в python)
Пояснение: функция float() преобразует строку в число. Если строку нельзя интерпретировать как число - генерируется исключение.
Проблема: float() принимает такие строки, как "inf", "nan", "1e5", что может быть нежелательно. Для строгого контроля - регулярное выражение. Также снижается производительность при большом количестве вызовов try/except.
Как подсчитать числа во вложенных строках или с нестандартными разделителями?
Метод re.finditer позволяет обрабатывать совпадения по одному, что полезно, если нужно параллельно извлекать позиции или контекст.
import re
text = "id=123, price=45.67, count=8"
pattern = r'\d+(\.\d+)?'
matches = re.finditer(pattern, text)
count = sum(1 for _ in matches)
print(count) # 3Пояснение: re.finditer возвращает итератор объектов Match. Суммируем единицы, не создавая списка всех совпадений.
Проблема: шаблон r'\d+(\.\d+)?' находит как целые, так и дробные числа, но также совпадёт с числом без дробной части. Если нужно считать только дробные - измените шаблон. Также следует учитывать, что шаблон не охватывает отрицательные числа.
Развёрнутые примеры с пояснениями
В этом разделе представлены более сложные сценарии подсчёта чисел в строке, включая работу с отрицательными значениями, числами в разных системах счисления и использование продвинутых функций.
Пример 1. Подсчёт отрицательных целых и дробных чисел
import re
text = "-5 и +3, а также -7.5 и 0.8"
# Регулярное выражение для чисел с возможным знаком и дробной частью
pattern = r'-?\d+(\.\d+)?'
matches = re.findall(pattern, text)
print(len(matches)) # 44
Пояснение: символ -? означает необязательный минус. \d+ - одна или более цифр. (\.\d+)? - необязательная дробная часть. Знак плюс игнорируется, так как он не является частью числа. При необходимости можно добавить поддержку + в шаблон: [+-]?\d+(\.\d+)?.
Пример 2. Использование filter и lambda для подсчёта чисел
text = "раз два 3.0 четыре 5"
# Разделяем по пробелам и фильтруем только те, что состоят из цифр и одной точки
def is_number(token):
return token.replace('.', '', 1).isdigit()
tokens = text.split()
count = len(list(filter(is_number, tokens)))
print(count) # 2 (3.0 и 5)2
Пояснение: filter применяет функцию к каждому элементу списка и возвращает итератор с элементами, для которых функция вернула True. Функция is_number удаляет первую точку, затем проверяет, что остались только цифры. Минус - такая проверка не распознаёт отрицательные числа.
Пример 3. Подсчёт шестнадцатеричных чисел (префикс 0x)
import re
text = "0xA, 0xFF и 123"
pattern = r'0x[0-9A-Fa-f]+|\d+'
matches = re.findall(pattern, text)
print(len(matches)) # 33
Пояснение: шаблон ищет либо последовательности, начинающиеся с 0x и содержащие шестнадцатеричные цифры, либо обычные десятичные числа. Альтернатива (через |) обеспечивает правильный приоритет. Если нужны только шестнадцатеричные числа - используйте только первую часть шаблона.
Пример 4. Ручной обход строки с накоплением
def count_numbers(text):
count = 0
i = 0
n = len(text)
while i < n:
if text[i].isdigit():
count += 1
while i < n and text[i].isdigit():
i += 1
else:
i += 1
return count
text = "Строка 123 с 4 и 56"
print(count_numbers(text)) # 33
Пояснение: проходим по строке слева направо. Как только встречаем цифру, увеличиваем счётчик и пропускаем всю последовательность цифр. Затем продолжаем. Метод не требует дополнительных модулей, но сложнее в поддержке (например, для дробных чисел потребуется модификация).
Пример 5. Подсчёт чисел с помощью map и sum
text = "10 20 30"
tokens = text.split()
count = sum(map(lambda t: 1 if t.isdigit() else 0, tokens))
print(count) # 33
Пояснение: map применяет функцию к каждому токену, возвращая итератор из 0 или 1. sum суммирует полученные значения. Альтернатива показана в основном разделе через генератор.