La plupart des questions que j'ai trouvées sont biaisées sur le fait qu'ils recherchent des lettres dans leurs nombres, alors que je recherche des nombres dans ce que j'aimerais être une chaîne infinie. Je dois entrer une chaîne et vérifier si elle contient des nombres et si elle la rejette.
La fonction isdigit()
ne renvoie que True
si TOUS les caractères sont des nombres. Je veux juste voir si l'utilisateur a entré un nombre donc une phrase comme "I own 1 dog"
ou quelque chose.
Des idées?
Réponses:
Vous pouvez utiliser la
any
fonction, avec lastr.isdigit
fonction, comme ceci>>> def hasNumbers(inputString): ... return any(char.isdigit() for char in inputString) ... >>> hasNumbers("I own 1 dog") True >>> hasNumbers("I own no dog") False
Vous pouvez également utiliser une expression régulière, comme celle-ci
>>> import re >>> def hasNumbers(inputString): ... return bool(re.search(r'\d', inputString)) ... >>> hasNumbers("I own 1 dog") True >>> hasNumbers("I own no dog") False
la source
r'-?\d+'
\d
ne correspondra qu'à un seul chiffre dans la plage0
à9
.Vous pouvez utiliser une combinaison de
any
etstr.isdigit
:def num_there(s): return any(i.isdigit() for i in s)
La fonction retournera
True
si un chiffre existe dans la chaîne, sinonFalse
.Démo:
>>> king = 'I shall have 3 cakes' >>> num_there(king) True >>> servant = 'I do not have any cakes' >>> num_there(servant) False
la source
any
accepte les expressions génératrices.utilisation
Réf: https://docs.python.org/2/library/stdtypes.html#str.isalpha
la source
'_'.isalpha()
est False.https://docs.python.org/2/library/re.html
Vous devriez mieux utiliser une expression régulière. C'est beaucoup plus rapide.
import re def f1(string): return any(i.isdigit() for i in string) def f2(string): return re.search('\d', string) # if you compile the regex string first, it's even faster RE_D = re.compile('\d') def f3(string): return RE_D.search(string) # Output from iPython # In [18]: %timeit f1('assdfgag123') # 1000000 loops, best of 3: 1.18 µs per loop # In [19]: %timeit f2('assdfgag123') # 1000000 loops, best of 3: 923 ns per loop # In [20]: %timeit f3('assdfgag123') # 1000000 loops, best of 3: 384 ns per loop
la source
None
Vous pouvez appliquer la fonction isdigit () sur chaque caractère de la chaîne. Ou vous pouvez utiliser des expressions régulières.
J'ai également trouvé Comment trouver un nombre dans une chaîne en Python? avec des moyens très appropriés pour renvoyer des nombres. La solution ci-dessous provient de la réponse à cette question.
number = re.search(r'\d+', yourString).group()
Alternativement:
Pour plus d'informations, consultez le docu regex: http://docs.python.org/2/library/re.html
Edit: Cela renvoie les nombres réels, pas une valeur booléenne, donc les réponses ci-dessus sont plus correctes pour votre cas
La première méthode renverra le premier chiffre et les chiffres consécutifs suivants. Ainsi 1.56 sera retourné comme 1. 10.000 sera retourné comme 10. 0207-100-1000 sera retourné comme 0207.
La deuxième méthode ne fonctionne pas.
Pour extraire tous les chiffres, points et virgules, et ne pas perdre de chiffres non consécutifs, utilisez:
re.sub('[^\d.,]' , '', yourString)
la source
Vous pouvez accomplir cela comme suit:
if a_string.isdigit(): do_this() else: do_that()
https://docs.python.org/2/library/stdtypes.html#str.isdigit
Utiliser
.isdigit()
signifie également ne pas avoir à recourir à la gestion des exceptions (try / except) dans les cas où vous avez besoin d'utiliser la compréhension de liste (try / except n'est pas possible dans une compréhension de liste).la source
Vous pouvez utiliser la méthode NLTK pour cela.
Cela trouvera à la fois '1' et 'One' dans le texte:
import nltk def existence_of_numeric_data(text): text=nltk.word_tokenize(text) pos = nltk.pos_tag(text) count = 0 for i in range(len(pos)): word , pos_tag = pos[i] if pos_tag == 'CD': return True return False existence_of_numeric_data('We are going out. Just five you and me.')
la source
Vous pouvez utiliser range with count pour vérifier combien de fois un nombre apparaît dans la chaîne en le comparant à la plage:
def count_digit(a): sum = 0 for i in range(10): sum += a.count(str(i)) return sum ans = count_digit("apple3rh5") print(ans) #This print 2
la source
Je suis surpris que personne n'ait mentionné cette combinaison de
any
etmap
:def contains_digit(s): isdigit = str.isdigit return any(map(isdigit,s))
en python 3, c'est probablement le plus rapide là-bas (sauf peut-être pour les regex) car il ne contient aucune boucle (et l'aliaser la fonction évite de la rechercher
str
).N'utilisez pas cela dans python 2 comme
map
retourne alist
, ce qui rompt leany
court-circuitla source
any
etord
peuvent être combinés pour atteindre l'objectif indiqué ci-dessous.>>> def hasDigits(s): ... return any( 48 <= ord(char) <= 57 for char in s) ... >>> hasDigits('as1') True >>> hasDigits('as') False >>> hasDigits('as9') True >>> hasDigits('as_') False >>> hasDigits('1as') True >>>
Quelques points sur cette implémentation.
any
est mieux car il fonctionne comme une expression de court-circuit en langage C et retournera le résultat dès qu'il pourra être déterminé, c'est-à-dire en cas de chaîne 'a1bbbbbbc' 'b's et' c's ne seront même pas comparés.ord
est mieux car il offre plus de flexibilité, comme les numéros de contrôle entre «0» et «5» ou toute autre plage. Par exemple, si vous deviez écrire un validateur pour la représentation hexadécimale des nombres, vous voudriez que la chaîne ait des alphabets dans la plage «A» à «F» uniquement.la source
Et celui-là?
import string def containsNumber(line): res = False try: for val in line.split(): if (float(val.strip(string.punctuation))): res = True break except ValueError: pass return res containsNumber('234.12 a22') # returns True containsNumber('234.12L a22') # returns False containsNumber('234.12, a22') # returns True
la source
Je vais rendre la réponse @zyxue un peu plus explicite:
RE_D = re.compile('\d') def has_digits(string): res = RE_D.search(string) return res is not None has_digits('asdf1') Out: True has_digits('asdf') Out: False
qui est la solution avec le benchmark le plus rapide parmi les solutions proposées par @zyxue sur la réponse.
la source
Un moyen plus simple de résoudre est de
s = '1dfss3sw235fsf7s' count = 0 temp = list(s) for item in temp: if(item.isdigit()): count = count + 1 else: pass print count
la source
import string import random n = 10 p = '' while (string.ascii_uppercase not in p) and (string.ascii_lowercase not in p) and (string.digits not in p): for _ in range(n): state = random.randint(0, 2) if state == 0: p = p + chr(random.randint(97, 122)) elif state == 1: p = p + chr(random.randint(65, 90)) else: p = p + str(random.randint(0, 9)) break print(p)
Ce code génère une séquence de taille n qui contient au moins une majuscule, une minuscule et un chiffre. En utilisant la boucle while, nous avons garanti cet événement.
la source
alp_num = [x for x in string.split() if x.isalnum() and re.search(r'\d',x) and re.search(r'[a-z]',x)] print(alp_num)
Cela renvoie toute la chaîne qui contient à la fois des alphabets et des nombres. isalpha () renvoie la chaîne avec tous les chiffres ou tous les caractères.
la source
Ce n'est probablement pas la meilleure approche en Python, mais en tant que Haskeller, cette approche lambda / map me semblait parfaitement logique et est très courte:
anydigit = lambda x: any(map(str.isdigit, x))
N'a pas besoin d'être nommé bien sûr. Nommé il pourrait être utilisé comme
anydigit("abc123")
, ce qui ressemble à ce que je cherchais!la source