Verifique se a string contém um número em Python

Introdução

Esteja você criando um script de verificação para entrada do usuário, um formulário de login que solicita que os usuários incluam um caractere em uma senha – verificar se uma string contém um caractere não é uma operação incomum.

Neste tutorial, veremos as várias maneiras de verificar se uma string contém um dígito/número em Python, incluindo um benchmark para a abordagem mais eficiente no final.

Verifique se a string contém o número em Python

Há várias maneiras de verificar se um personagem é um número (ord(), isnumeric(), isdigit()), que você pode associar a um loop for, para verificar se há pelo menos um único acerto positivo. Como alternativa, você pode usar expressões regulares como correspondências de padrão geral, que são flexíveis, poderosas e projetadas para serem aplicadas a grandes corpus de texto. Finalmente - você sempre pode map() cada personagem recebe uma declaração condicional e retorna True is any() deles resultam em True.

A escolha entre eles deve levar em consideração a eficiência dos métodos, verbosidade e estilo de codificação, bem como tarefas upstream ou downstream associadas à operação.

Verifique se a string contém o número com ord ()

A ord() função pega um caractere e retorna seu ASCII valor:

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

O valor ASCII de 0 é 48, e o valor ASCII de 9 é 57. Qualquer número entre estes, por extensão, ter um valor ASCII entre 48 e 57. Agora, para verificar se a string tem algum número, vamos percorrer toda a string de entrada e verificar o valor ASCII de cada caractere, se o valor ASCII for maior que 47 e menor que 58, significa que é um número e retornaremos 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.")

Isto resulta em:

Yes, the string contains a number.

Verifique se a string contém o número com isnumeric ()

A isnumeric() função retorna True se a string de entrada contiver apenas números, caso contrário, retornará 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())

Isto resulta em:

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

Observação: A isnumeric() função não se comportará como você pode esperar para números negativos ou flutuantes. Se passarmos uma string apenas com números negativos ou float, ela retornará False, Porque o - e . caracteres associados a números negativos e flutuantes são, de fato, não números.

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

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

Porém, como os caracteres são apenas strings de comprimento 1 em Python – você pode iterar pelos caracteres e usar isnumeric() para verificar se eles são um número:

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.")

Verifique se a string contém o número com isdigit ()

A isdigit() A função verifica se todos os caracteres em uma string são dígitos. Se sim - ele retorna True, e se não, ele retorna False. Novamente, como os caracteres são apenas strings de comprimento 1 em Python – esse método pode ser usado em um loop para cada caractere:

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.")

Observação: A isdigit() método só se comporta da mesma maneira que isnumeric(), e se você passar uma string contendo um float ou um número negativo para ela, False é retornado porque os caracteres especiais não são números. Em um nível de personagem, porém, se contanto que um True value é suficiente para determinar se a string contém um número – é aplicável.

Diferença entre isnumeric () e isdigit ()?

Então, qual é a diferença entre isnumeric() e isdigit()? Enquanto estamos nisso - e quanto a isdecimal()?

  • isnumeric() verifica se algum caractere é um representação unicode de uma valor numérico (que inclui representações numéricas romanas, sobrescritos, subscritos e frações)
  • isdigit() verifica se algum caractere é um dígito unicode (que não inclui representações numéricas romanas, mas inclui super/subscritos e frações)
  • isdecimal() verifica se algum caractere é um dígito decimal (que retornaria False por qualquer coisa que não seja 0..9 na base 10)

isnumeric() é o método mais amplo, enquanto isdecimal() é o mais estreito entre os três.

Verifique se a string contém o número com map () e any ()

A map() A função executa a função fornecida para cada elemento do iterável passado na função map. Cada elemento de um iterável é passado para a função como um parâmetro:

map(function, iterable)

A function é executado para cada item do iterable. Isso permite uma lógica muito flexível e poderosa, limitada apenas pela extensão do function você chama na entrada! O método retorna um map instância, que pode ser facilmente transformada em outras coleções, como uma lista ou conjunto.

Podemos escrever uma função que retorna um booleano representando se um caractere é um número e o map() call resultará em uma lista de valores booleanos.

A any() Retorna True se algum elemento do iterável passado for True, caso contrário, retorna False.

Juntando esses dois – podemos criar um script curto de alto nível e abstrair o loop 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)

Isto resulta em:

Is there a number present? True

Se sua função for de uma linha - não há necessidade de extraí-la como uma função nomeada. Você pode escrever um anônimo função lambda em vez disso, por uma questão de brevidade:

Confira nosso guia prático e prático para aprender Git, com práticas recomendadas, padrões aceitos pelo setor e folha de dicas incluída. Pare de pesquisar comandos Git no Google e realmente aprender -lo!

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)

Isso também resulta em:

Is there any number present? True

Verifique se a string contém o número em Python com expressões regulares

Expressões Regulares são padrões de pesquisa projetado para corresponder ao texto de entrada. Eles são flexíveis e devido à sua natureza - você pode escrever um número arbitrário de expressões para o mesmo padrão a ser pesquisado, bem como cobrir qualquer padrão tratável que você possa imaginar.

Python's re O módulo é usado para escrever, compilar e combinar texto com expressões regulares. Ele expõe vários métodos, como match() que corresponde se uma string começa com um padrão, search() que encontra a primeira ocorrência de possivelmente muitas correspondências em uma string e findall() que verifica todas as ocorrências.

Observação: Todos os três métodos aceitam um pattern e search argumento e faça uma busca pelo pattern no search string.

O padrão que identifica um dígito 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")

A search() método retorna um re.Match objeto, contendo a correspondência encontrada e os índices inicial e final:


O objeto pode ser avaliado para um valor booleano com base em se é um re.Match objeto ou None. Isto resulta em:

Is there any number present? Yes

Ao contrário do search() método, o findall() O método retorna todas as ocorrências do padrão em vez de apenas a primeira:

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")

Isto resulta em:

Is there any number present? Yes

O benchmarking

E o desempenho? Se você extrair a lógica e cortar as partes desnecessárias, limitando os métodos para retornar apenas o resultado, você pode compará-los facilmente um contra o outro na mesma entrada:

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

Isto resulta em:

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)

Geralmente, as abordagens de loop for são executadas ao mesmo tempo, com pouca sobrecarga dos métodos específicos. Lambda com any() é de fato o mais lento (muitas operações redundantes, devido à conversão de uma lista em uma lista e depois reduzi-la), enquanto as Expressões Regulares tiveram o tempo de execução mais rápido com a menor variação em torno dele (elas são consistentemente rápidas).

No entanto, em textos de entrada mais longos, as complexidades de tempo em cada uma das diferentes abordagens são enfatizadas, especialmente dependendo do número de dígitos correspondentes (sendo os dígitos comuns ou não):

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) 

A primeira string gera uma sequência aleatória com um número aproximadamente igual de dígitos e caracteres, enquanto a última é uma string somente de caracteres com um único dígito no final (pior complexidade de tempo):

%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)

Com um baixo número de acertos – Expressões Regulares são as de melhor desempenho. Com muitos acessos, a abordagem da função lambda é a de melhor desempenho e mantém sua complexidade de tempo independentemente de a entrada ter muitos hits ou um. A principal desvantagem (computação redundante quando a taxa de acerto é baixa) é transformada em sua principal força, pois a redundância o torna robusto para entrada.

Conclusão

Neste tutorial, examinamos várias maneiras de verificar se uma string em Python contém pelo menos um caractere. Demos uma olhada no ord(), isnumeric(), isdigit() e isdecimal() função, bem como como abstrair essa lógica com uma chamada de função lambda usando map() e any(). Em seguida, exploramos as expressões regulares e comparamos as abordagens com entradas variadas.

Carimbo de hora:

Mais de Abuso de pilha