Проверить, содержит ли строка число в Python

Введение

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

В этом уроке мы рассмотрим множество способов, которыми вы можете проверить, содержит ли строка цифру/число в Python, включая тест для наиболее эффективного подхода в конце.

Проверьте, содержит ли строка число в Python

Существует несколько способов проверить, является ли персонаж это число (ord(), isnumeric(), isdigit()), который вы можете соединить с циклом for, чтобы проверить хотя бы одно положительное совпадение. Кроме того, вы можете использовать регулярные выражения в качестве общих средств сопоставления с образцом, которые являются гибкими, мощными и предназначены для применения к большим объемам текста. В конце концов, вы всегда можете map() каждый символ, заданный условным оператором, и возврат True is any() из них приводят к True.

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

Проверьте, содержит ли строка число с помощью ord()

Ассоциация ord() функция принимает символ и возвращает его ASCII значение:

print(ord('0')) 
print(ord('9')) 

Значение ASCII 0 равно 48, а значение ASCII 9 равно 57. Любое число между этими числами, соответственно, будет иметь значение ASCII от 48 до 57. Теперь, чтобы проверить, есть ли в строке какое-либо число, мы пройдем всю входную строку и проверим значение ASCII каждого символа, если значение ASCII больше 47 и меньше 58, это означает, что это число, и мы вернемся True:

input_string = "My name is Satyam & I am 22 yrs old"
flag = False
for ch in input_string:
    ascii_code = ord(ch)
    if 47 < ascii_code < 58:
        flag = True
        break
if flag:
    print("Yes, the string contains a number.")
else:
    print("No, the string does not contain a number.")

Это приводит к:

Yes, the string contains a number.

Проверьте, содержит ли строка число с помощью isnumeric()

Ассоциация isnumeric() возвращает функцию True если входная строка содержит только числа, иначе возвращает False:

str1 = "918"
print("String is whole numeric?", str1.isnumeric())
str2 = "The meaning of the universe is 42"
print("String is whole numeric?", str2.isnumeric())

Это приводит к:

String is whole numeric? True 
String is whole numeric? False

Примечание: Ассоциация isnumeric() функция не будет вести себя так, как вы можете ожидать для отрицательные или плавающие числа. Если мы передаем строку только с отрицательными числами или числами с плавающей запятой, она вернет False, Потому что - и . символы, связанные с отрицательными числами и числами с плавающей запятой, действительно не являются числами.

str1 = "-918"
print("String is whole numeric?", str1.isnumeric()) 

str2 = "91.8"
print("String is whole numeric?", str2.isnumeric()) 

Однако, поскольку символы в Python — это просто строки длины 1, вы можете перебирать символы и использовать isnumeric() чтобы проверить, являются ли они числом:

input_string = "My name is Satyam & I am 22 yrs old"
flag = False
for ch in input_string:
    if ch.isnumeric():
        flag = True
        break
if flag:
    print("Yes, the string contains a number.")
else:
    print("No, the string does not contain a number.")

Проверьте, содержит ли строка число с помощью isdigit()

Ассоциация isdigit() Функция проверяет, все ли символы в строке являются цифрами. Если да - возвращает True, а если нет, то возвращает False. Опять же, поскольку символы в Python — это просто строки длины 1, этот метод можно использовать в цикле для каждого символа:

input_string = "My name is Satyam & I am 22 yrs old"
flag = False
for ch in input_string:
    if ch.isdigit():
        flag = True
        break
if flag:
    print("Yes, the string contains a number.")
else:
    print("No, the string does not contain a number.")

Примечание: Ассоциация isdigit() метод ведет себя так же, как isnumeric(), и если вы передадите ему строку, содержащую число с плавающей запятой или отрицательное число, False возвращается из-за того, что специальные символы не являются числами. Однако на уровне персонажа, если до тех пор, пока один True value достаточно, чтобы определить, содержит ли строка число — оно применимо.

Разница между isnumeric() и isdigit()?

Итак, в чем разница между isnumeric() и isdigit()? Пока мы в этом - что насчет isdecimal()?

  • isnumeric() проверяет, является ли какой-либо символ представление юникода в А числовое значение (который включает римские числовые представления, верхние индексы, нижние индексы и дроби)
  • isdigit() проверяет, является ли какой-либо символ юникод цифра (который не включает римские числовые представления, но включает надстрочные/нижние индексы и дроби)
  • isdecimal() проверяет, является ли какой-либо символ десятичная цифра (который вернет False за все, что не 0..9 в базе 10)

isnumeric() является наиболее широким методом, в то время как isdecimal() является самым узким из трех.

Проверьте, содержит ли строка число с помощью map() и any()

Ассоциация map() функция выполняет предоставленную функцию для каждого элемента итерируемого объекта, переданного в функцию карты. Каждый элемент итерации передается функции в качестве параметра:

map(function, iterable)

Ассоциация function выполняется для каждого элемента iterable. Это позволяет использовать очень гибкую и мощную логику, ограниченную только экстенсивностью function Вы звоните на вход! Метод возвращает map экземпляр, который можно легко превратить в другие коллекции, такие как список или набор.

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

Ассоциация any() Возвращает True если какой-либо элемент переданной итерации True, иначе возвращается False.

Соединив эти две вещи вместе, мы можем создать высокоуровневый короткий скрипт и абстрагировать цикл for:

def func(ch):
    return ch.isdigit() 

input_string = "My name is Satyam & I am 22 yrs old"
contains_number = any(list(map(func, input_string)))
print("Is there a number present?", contains_number)

Это приводит к:

Is there a number present? True

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

Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!

input_string = "My name is Satyam & I am 22 yrs old"
contains_number = any(list(map(lambda ch: ch.isdigit(), input_string)))
print("Is there any number present?", contains_number)

Это также приводит к:

Is there any number present? True

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

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

Python re Модуль используется для записи, компиляции и сопоставления текста с регулярными выражениями. Он раскрывает различные методы, такие как match() который соответствует тому, начинается ли строка с шаблона, search() который находит первое вхождение, возможно, многих совпадений в строке, и findall() который проверяет все вхождения.

Примечание: Все три метода принимают pattern и search аргумент и запустить поиск pattern в search строка.

Образец, который идентифицирует цифра is "d+":

import re
input_string = "My name is Satyam & I am 22 yrs old"
match = re.search(r"d+", input_string)
if match:
    print("Is there any number present?", "Yes")
else:
    print("Is there any number present?", "No")

Ассоциация search() метод возвращает re.Match объект, содержащий найденное совпадение и начальный и конечный индексы:


Объект может оцениваться как логическое значение в зависимости от того, является ли он re.Match объект или None. Это приводит к:

Is there any number present? Yes

В отличие от search() Метод, findall() метод возвращает все вхождения шаблона, а не только первое:

import re
input_string = "My name is Satyam & I am 22 yrs old"
match = re.findall(r"d+", input_string)
if match:
    print("Is there any number present?", "Yes")
else:
    print("Is there any number present?", "No")

Это приводит к:

Is there any number present? Yes

Производительность системы

Как насчет производительности? Если вы извлечете логику и обрежете ненужные части, ограничив методы только возвратом результата, вы можете легко сравнить их друг с другом на одном и том же входе:

%timeit ord_check()
%timeit isnumeric_check()
%timeit is_digit_check()
%timeit lambda_check()
%timeit regex_check()

Это приводит к:

2.18 µs ± 51.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
2.04 µs ± 639 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
1.88 µs ± 448 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
5.07 µs ± 915 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
1.47 µs ± 3.41 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

Как правило, подходы с циклом for выполняются примерно в одно и то же время с небольшими накладными расходами от конкретных методов. лямбда с any() де-факто является самым медленным (много избыточных операций из-за преобразования списка в список и последующего его сокращения), в то время как регулярные выражения имели самое быстрое время выполнения с наименьшей дисперсией вокруг него (они неизменно быстрые).

Однако в более длинных входных текстах подчеркивается временная сложность каждого из различных подходов, особенно в зависимости от количества совпадающих цифр (независимо от того, являются ли цифры общими или нет):

import random
import string

input_string_random = ''.join(random.choices(string.ascii_uppercase + string.digits, k=1000))
print(input_string_random) 

input_string_with_single_digit = ''.join(random.choices(string.ascii_uppercase, k=1000)) + '1'
print(input_string_with_single_digit) 

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

%timeit ord_check(input_string_random)
504 ns ± 22.6 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit ord_check(input_string_with_single_digit)
76.2 µs ± 1.36 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit isnumeric_check(input_string_random)
756 ns ± 170 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit isnumeric_check(input_string_with_single_digit)
76.2 µs ± 8.43 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit is_digit_check(input_string_random)
549 ns ± 102 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit is_digit_check(input_string_with_single_digit)
65 µs ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit lambda_check(input_string_random)
114 µs ± 8.77 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit lambda_check(input_string_with_single_digit)
119 µs ± 6.23 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit regex_check(input_string_random)
996 ns ± 19.8 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
%timeit regex_check(input_string_with_single_digit)
22.2 µs ± 1.77 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

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

Заключение

В этом уроке мы рассмотрели несколько способов проверить, содержит ли строка в Python хотя бы один символ. Мы взглянули на ord(), isnumeric(), isdigit() и isdecimal() функции, а также как абстрагировать эту логику с помощью вызова лямбда-функции, используя map() и any(). Затем мы изучили регулярные выражения и сравнили подходы с различными входными данными.

Отметка времени:

Больше от Стекабьюс