Controlla se la stringa contiene un numero in Python

Introduzione

Sia che tu stia creando uno script di verifica per l'input dell'utente, un modulo di accesso che richiede agli utenti di includere un carattere in una password, verificare se una stringa contiene un carattere non è un'operazione insolita.

In questo tutorial daremo un'occhiata ai molti modi in cui puoi verificare se una stringa contiene una cifra/numero in Python, incluso un punto di riferimento per l'approccio più efficiente alla fine.

Controlla se la stringa contiene un numero in Python

Esistono diversi modi per verificare se a carattere è un numero (ord(), isnumeric(), isdigit()), che puoi accoppiare con un ciclo for, per verificare almeno un singolo colpo positivo. In alternativa, puoi utilizzare le espressioni regolari come modelli di corrispondenza generali, che sono flessibili, potenti e progettati per essere applicati a grandi corpus di testo. Finalmente puoi sempre map() ad ogni carattere viene data un'istruzione condizionale e ritorna True is any() di essi risultano True.

La scelta tra questi dovrebbe prendere in considerazione l'efficienza dei metodi, la verbosità e lo stile di codifica, nonché le attività a monte o a valle associate all'operazione.

Controlla se la stringa contiene un numero con ord()

I ord() la funzione prende un carattere e lo restituisce ASCII valore:

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

Il valore ASCII di 0 è 48 e il valore ASCII di 9 è 57. Qualsiasi numero tra questi, per estensione, avere un valore ASCII compreso tra 48 e 57. Ora per verificare se la stringa ha qualche numero, attraverseremo l'intera stringa di input e controlleremo il valore ASCII di ciascun carattere, se il valore ASCII è maggiore di 47 e minore di 58, significa che è un numero e restituiremo 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.")

Questo risulta in:

Yes, the string contains a number.

Controlla se la stringa contiene un numero con isnumeric()

I isnumeric() funzione restituisce True se la stringa di input contiene solo numeri, altrimenti restituisce 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())

Questo risulta in:

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

Nota: I isnumeric() la funzione non si comporterà come previsto numeri negativi o float. Se passiamo una stringa con solo numeri negativi o float, restituirà False, Poiché l' - ed . i caratteri associati ai numeri negativi e ai numeri in virgola mobile infatti non sono numeri.

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

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

Tuttavia, poiché i caratteri sono solo stringhe di lunghezza 1 in Python, puoi scorrere i caratteri e utilizzare isnumeric() per verificare se sono un numero:

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

Controlla se la stringa contiene un numero con isdigit()

I isdigit() la funzione controlla se tutti i caratteri in una stringa sono cifre. Se sì, ritorna Truee, in caso contrario, ritorna False. Ancora una volta, poiché i caratteri sono solo stringhe di lunghezza 1 in Python, questo metodo può essere utilizzato in un ciclo per ciascun carattere:

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

Nota: I isdigit() Il metodo si comporta solo nello stesso modo di isnumeric()e se le passi una stringa contenente un numero in virgola mobile o negativo, False viene restituito perché i caratteri speciali non sono numeri. A livello di personaggio, però, anche se lungo quanto uno True value è sufficiente per determinare se la stringa contiene un numero: è applicabile.

Differenza tra isnumeric() e isdigit()?

Allora, qual è la differenza tra isnumeric() ed isdigit()? Già che ci siamo, che ne dici? isdecimal()?

  • isnumeric() controlla se qualche carattere è a rappresentazione unicode di uno valore numerico (che include rappresentazioni numeriche romane, apici, pedici e frazioni)
  • isdigit() controlla se qualche carattere è a cifra unicode (che non include rappresentazioni numeriche romane, ma include apici/pedici e frazioni)
  • isdecimal() controlla se qualche carattere è a cifra decimale (che ritornerebbe False per tutto ciò che non lo è 0..9 nella base 10)

isnumeric() è il metodo più ampio, mentre isdecimal() è il più stretto tra i tre.

Controlla se la stringa contiene un numero con map() e any()

I map() La funzione esegue la funzione fornita per ogni elemento dell'iterabile passato nella funzione map. Ogni elemento di un iterabile viene passato alla funzione come parametro:

map(function, iterable)

I function viene eseguito per ogni elemento di iterable. Ciò consente una logica molto flessibile e potente, limitata solo dall'ampiezza del file function chiami sull'input! Il metodo restituisce a map esempio, che può essere facilmente trasformato in altre raccolte come un elenco o un set.

Possiamo scrivere una funzione che restituisca un valore booleano che rappresenta se un carattere è un numero e il map() call risulterà quindi in un elenco di valori booleani.

I any() problemi True se qualsiasi elemento dell'iterabile passato lo è True, altrimenti ritorna False.

Mettendo insieme questi due elementi, possiamo creare uno script breve e di alto livello e astrarre il ciclo 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)

Questo risulta in:

Is there a number present? True

Se la tua funzione è one-liner, non è necessario estrarla come funzione con nome. Puoi scrivere un anonimo funzione lambda invece per brevità:

Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!

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)

Ciò comporta anche:

Is there any number present? True

Controlla se la stringa contiene un numero in Python con espressioni regolari

Le espressioni regolari lo sono modelli di ricerca progettato per essere abbinato al testo di input. Sono flessibili e, data la loro natura, puoi scrivere un numero arbitrario di espressioni per lo stesso modello da cercare, oltre a coprire qualsiasi modello trattabile che ti viene in mente.

Python's re il modulo viene utilizzato per scrivere, compilare e confrontare il testo con le espressioni regolari. Espone vari metodi, come ad esempio match() che verifica se una stringa inizia con un modello, search() che trova la prima occorrenza di un numero possibile di corrispondenze in una stringa e findall() che controlla tutte le occorrenze.

Nota: Tutti e tre i metodi accettano a pattern ed search argomento ed eseguire una ricerca per il file pattern nel search stringa.

Il modello che identifica a cifra 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")

I search() metodo restituisce un file re.Match oggetto, contenente la corrispondenza trovata e gli indici iniziale e finale:


L'oggetto può essere valutato con un valore booleano a seconda che sia a re.Match oggetto o None. Questo risulta in:

Is there any number present? Yes

Diversamente dal search() metodo, la findall() Il metodo restituisce tutte le occorrenze del modello anziché solo la prima:

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

Questo risulta in:

Is there any number present? Yes

Benchmarking

E la prestazione? Se estrai la logica e rifili le parti non necessarie, limitando i metodi a restituire solo il risultato, puoi facilmente confrontarli uno con l'altro sullo stesso input:

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

Questo risulta in:

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)

Generalmente gli approcci for-loop vengono eseguiti più o meno nello stesso tempo, con un sovraccarico minimo da parte dei metodi specifici. Lambda con any() è di fatto il più lento (molte operazioni ridondanti, dovute alla conversione di un elenco in un elenco e quindi alla sua riduzione), mentre le espressioni regolari hanno avuto il runtime più veloce con la varianza più bassa attorno ad esso (sono costantemente veloci).

Tuttavia, su testi di input più lunghi, le complessità temporali su ciascuno dei diversi approcci vengono enfatizzate, soprattutto a seconda del numero di cifre corrispondenti (se le cifre sono comuni o meno):

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) 

La prima stringa genera una sequenza casuale con un numero circa uguale di cifre e caratteri, mentre la seconda è una stringa di soli caratteri con una singola cifra alla fine (complessità peggiore):

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

Con un numero basso di risultati: le espressioni regolari sono le più performanti. Con molti successi, l'approccio della funzione lambda è il più performante, e it mantiene la sua complessità temporale indipendentemente dal fatto che l'input abbia molti risultati o uno solo. Lo svantaggio principale (calcolo ridondante quando il tasso di successo è basso) si trasforma nel suo principale punto di forza poiché la ridondanza lo rende robusto da inserire.

Conclusione

In questo tutorial, abbiamo esaminato diversi modi per verificare se una stringa in Python contiene almeno un carattere. Abbiamo dato un'occhiata a ord(), isnumeric(), isdigit() ed isdecimal() funzione, nonché come astrarre questa logica con una chiamata alla funzione lambda utilizzando map() ed any(). Successivamente, abbiamo esplorato le espressioni regolari e confrontato gli approcci con input diversi.

Timestamp:

Di più da Impilamento