Vérifier si la chaîne contient un nombre en Python

Introduction

Que vous créiez un script de vérification pour la saisie de l'utilisateur ou un formulaire de connexion qui demande aux utilisateurs d'inclure un caractère dans un mot de passe, vérifier si une chaîne contient un caractère n'est pas une opération rare.

Dans ce didacticiel, nous examinerons les nombreuses façons dont vous pouvez vérifier si une chaîne contient un chiffre/un nombre en Python, y compris un benchmark pour l'approche la plus efficace au final.

Vérifier si la chaîne contient un nombre en Python

Il existe plusieurs façons de vérifier si un caractère est un nombre (ord(), isnumeric(), isdigit()), que vous pouvez coupler avec une boucle for, pour vérifier au moins un seul résultat positif. Vous pouvez également utiliser des expressions régulières comme outils de correspondance de modèles généraux, qui sont flexibles, puissants et conçus pour être appliqués à de grands corpus de texte. Enfin – vous pouvez toujours map() chaque caractère donné une déclaration conditionnelle, et retour True is any() d'entre eux entraînent True.

Le choix entre ceux-ci doit tenir compte de l'efficacité des méthodes, de la verbosité et du style de codage, ainsi que des tâches en amont ou en aval associées à l'opération.

Vérifiez si la chaîne contient un nombre avec ord ()

Les ord() fonction prend un caractère et renvoie son ASCII valeur:

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

La valeur ASCII de 0 est 48, et la valeur ASCII de 9 est 57. Tout nombre entre ceux-ci, par extension, avoir une valeur ASCII entre 48 et 57. Maintenant, pour vérifier si la chaîne a un nombre, nous allons parcourir toute la chaîne d'entrée et vérifier la valeur ASCII de chaque caractère, si la valeur ASCII est supérieure à 47 et inférieure à 58, cela signifie que c'est un nombre, et nous reviendrons 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.")

Cela se traduit par:

Yes, the string contains a number.

Vérifiez si la chaîne contient un nombre avec isnumeric()

Les isnumeric() la fonction retourne True si la chaîne d'entrée ne contient que des nombres, sinon, elle renvoie 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())

Cela se traduit par:

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

Remarque: Les isnumeric() la fonction ne se comportera pas comme prévu pour nombres négatifs ou flottants. Si nous passons une chaîne avec uniquement des nombres négatifs ou flottants, elle renverra False, Parce que le - ainsi que . les caractères associés aux nombres négatifs et aux flottants ne sont en effet pas des nombres.

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

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

Cependant, comme les caractères ne sont que des chaînes de longueur 1 en Python, vous pouvez parcourir les caractères et utiliser isnumeric() pour vérifier s'il s'agit d'un numéro :

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

Vérifiez si la chaîne contient un nombre avec isdigit ()

Les isdigit() La fonction vérifie si tous les caractères d'une chaîne sont des chiffres. Si oui, il revient True, et sinon, il retourne False. Encore une fois, puisque les caractères ne sont que des chaînes de longueur 1 en Python, cette méthode peut être utilisée dans une boucle pour chaque caractère :

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

Remarque: Les isdigit() méthode se comporte uniquement de la même manière que isnumeric(), et si vous lui transmettez une chaîne contenant un flottant ou un nombre négatif, False est renvoyé car les caractères spéciaux ne sont pas des nombres. Au niveau du personnage, cependant, si tant qu'un True La valeur est suffisante pour déterminer si la chaîne contient un nombre – c’est applicable.

Différence entre isnumeric() et isdigit() ?

Alors, quelle est la différence entre isnumeric() ainsi que isdigit()? Pendant que nous y sommes, qu'en est-il isdecimal()?

  • isnumeric() vérifie si un caractère est un représentation unicode d'un valeur numérique (qui comprend les représentations numériques romaines, les exposants, les indices et les fractions)
  • isdigit() vérifie si un caractère est un chiffre unicode (qui n'inclut pas les représentations numériques romaines, mais inclut les super/indices et les fractions)
  • isdecimal() vérifie si un caractère est un chiffre décimal (qui reviendrait False pour tout ce qui n'est pas 0..9 en socle 10)

isnumeric() est la méthode la plus large, tandis que isdecimal() est le plus étroit des trois.

Vérifiez si la chaîne contient un nombre avec map() et any()

Les map() La fonction exécute la fonction fournie pour chaque élément de l'itérable passé dans la fonction map. Chaque élément d'un itérable est passé à la fonction en tant que paramètre :

map(function, iterable)

Les function est exécuté pour chaque élément du iterable. Cela permet une logique très flexible et puissante, limitée uniquement par l'étendue de la function vous appelez sur l'entrée! La méthode retourne un map instance, qui peut être facilement transformée en d'autres collections telles qu'une liste ou un ensemble.

Nous pouvons écrire une fonction qui renvoie un booléen représentant si un caractère est un nombre, et le map() call se traduira donc par une liste de valeurs booléennes.

Les any() Retours True si un élément de l'itérable passé est True, sinon, il retourne False.

En enchaînant ces deux éléments ensemble, nous pouvons créer un script court et de haut niveau et faire abstraction de la boucle 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)

Cela se traduit par:

Is there a number present? True

Si votre fonction est une ligne unique, il n'est pas nécessaire de l'extraire en tant que fonction nommée. Vous pouvez écrire un anonyme fonction lambda au lieu de cela, par souci de brièveté :

Consultez notre guide pratique et pratique pour apprendre Git, avec les meilleures pratiques, les normes acceptées par l'industrie et la feuille de triche incluse. Arrêtez de googler les commandes Git et en fait apprendre il!

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)

Cela se traduit également par:

Is there any number present? True

Vérifiez si la chaîne contient un nombre en Python avec des expressions régulières

Les expressions régulières sont modèles de recherche conçu pour être comparé au texte saisi. Ils sont flexibles et, compte tenu de leur nature, vous pouvez écrire un nombre arbitraire d'expressions pour le même modèle à rechercher, ainsi que couvrir n'importe quel modèle traitable auquel vous pouvez penser.

Python re module est utilisé pour écrire, compiler et faire correspondre du texte avec des expressions régulières. Il expose diverses méthodes, telles que match() qui correspond si une chaîne commence par un motif, search() qui trouve la première occurrence d'éventuellement plusieurs correspondances dans une chaîne, et findall() qui vérifie toutes les occurrences.

Remarque: Les trois méthodes acceptent une pattern ainsi que search argument et lancer une recherche pour le pattern dans l' search chaîne.

Le motif qui identifie un chiffre 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")

Les search() méthode retourne un re.Match objet, contenant la correspondance trouvée et les indices de début et de fin :


L'objet peut être évalué à une valeur booléenne selon qu'il s'agit ou non d'un re.Match objet ou None. Cela se traduit par :

Is there any number present? Yes

Contrairement au search() Procédé, l' findall() renvoie toutes les occurrences du motif au lieu de la première uniquement :

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

Cela se traduit par:

Is there any number present? Yes

Benchmarking

Qu'en est-il des performances ? Si vous extrayez la logique et supprimez les parties inutiles, en limitant les méthodes à renvoyer uniquement le résultat, vous pouvez facilement les comparer les unes aux autres sur la même entrée :

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

Cela se traduit par:

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)

Généralement, les approches de boucle for s'exécutent à peu près au même moment, avec peu de surcharge des méthodes spécifiques. Lambda avec any() est de facto le plus lent (beaucoup d'opérations redondantes, dues à la conversion d'une liste en liste puis à sa réduction), tandis que les expressions régulières avaient le temps d'exécution le plus rapide avec la plus faible variance (elles sont toujours rapides).

Cependant, sur des textes d'entrée plus longs, les complexités temporelles de chacune des différentes approches sont soulignées, en particulier en fonction du nombre de chiffres correspondants (que les chiffres soient communs ou non) :

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 première chaîne génère une séquence aléatoire avec un nombre à peu près égal de chiffres et de caractères, tandis que la seconde est une chaîne de caractères uniquement avec un seul chiffre à la fin (pire complexité temporelle) :

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

Avec un faible nombre de hits, les expressions régulières sont les plus performantes. Avec de nombreux succès, l'approche de la fonction lambda est la plus performante, et elle conserve sa complexité temporelle indépendamment du fait que l'entrée a plusieurs hits ou un. Le principal inconvénient (calcul redondant lorsque le taux de réussite est faible) est transformé en sa principale force car la redondance le rend robuste à l'entrée.

Conclusion

Dans ce didacticiel, nous avons examiné plusieurs façons de vérifier si une chaîne en Python contient au moins un caractère. Nous avons jeté un oeil à ord(), isnumeric(), isdigit() ainsi que isdecimal() fonction, ainsi que la façon d'abstraire cette logique avec un appel de fonction lambda en utilisant map() ainsi que any(). Ensuite, nous avons exploré les expressions régulières et comparé les approches avec différentes entrées.

Horodatage:

Plus de Stackabuse