Введение
Создаете ли вы сценарий проверки для пользовательского ввода, форму входа, которая просит пользователей включить символ в пароль — проверка того, содержит ли строка символ, не является необычной операцией.
В этом уроке мы рассмотрим множество способов, которыми вы можете проверить, содержит ли строка цифру/число в 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()
. Затем мы изучили регулярные выражения и сравнили подходы с различными входными данными.