Comment vérifier si une chaîne est un nombre (float)?
Quelle est la meilleure façon de vérifier si une chaîne peut être représentée sous forme de nombre en Python?
la fonction que j'ai actuellement est:
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
qui, non seulement est laid et lent, semble grotesque. Cependant, je n'ai pas trouvé de meilleure méthode car appeler float
dans la fonction principale est encore pire.
30 réponses
qui, non seulement est laid et lent
Je contesterais les deux.
une analyse regex ou une autre chaîne de caractères serait plus laide et plus lente.
Je ne suis pas sûr que beaucoup puisse être plus rapide que ce qui précède. Il appelle la fonction et retourne. Try / Catch n'introduit pas beaucoup de overhead parce que l'exception la plus commune est capturée sans une recherche extensive des cadres de pile.
Le problème est que toute fonction de conversion numérique a deux types de résultats
- Un numéro si le numéro est valide
- un code d'état (par exemple, via errno) ou une exception pour montrer qu'aucun numéro valide ne pouvait être interprété.
C (à titre d'exemple) pirate ce un certain nombre de façons. Python pose clairement et explicitement.
je pense que votre code pour faire ça est parfait.
dans le cas où vous recherchez parsing (positif, non signé) des entiers au lieu de flotteurs, vous pouvez utiliser la fonction isdigit()
pour les objets string.
>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False
il y a aussi quelque chose sur les chaînes Unicode, que je ne connais pas très bien. Unicode Est décimal/decimal
TL; DR la meilleure solution est s.replace('.','',1).isdigit()
j'ai fait quelques repères la comparaison des différentes approches
def is_number_tryexcept(s):
""" Returns True is string is a number. """
try:
float(s)
return True
except ValueError:
return False
import re
def is_number_regex(s):
""" Returns True is string is a number. """
if re.match("^\d+?\.\d+?$", s) is None:
return s.isdigit()
return True
def is_number_repl_isdigit(s):
""" Returns True is string is a number. """
return s.replace('.','',1).isdigit()
si la chaîne n'est pas un nombre, le bloc excepté est assez lent. Mais plus important encore, la méthode try-except est la seule approche qui traite correctement les notations scientifiques.
funcs = [
is_number_tryexcept,
is_number_regex,
is_number_repl_isdigit
]
a_float = '.1234'
print('Float notation ".1234" is not supported by:')
for f in funcs:
if not f(a_float):
print('\t -', f.__name__)
Float notation".1234" n'est pas supporté par:
- is_number_regex
scientific1 = '1.000000e+50'
scientific2 = '1e50'
print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
if not f(scientific1):
print('\t -', f.__name__)
print('Scientific notation "1e50" is not supported by:')
for f in funcs:
if not f(scientific2):
print('\t -', f.__name__)
notation Scientifique "1.000000 e+50" n'est pas pris en charge par:
- is_number_regex
- is_number_repl_isdigit
La notation scientifique "1e50" n'est pas supportée par:
- is_number_regex
- is_number_repl_isdigit
EDIT: les résultats de référence
import timeit
test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}
for t in test_cases:
for f in funcs:
f = f.__name__
times_n[f].append(min(timeit.Timer('%s(t)' %f,
'from __main__ import %s, t' %f)
.repeat(repeat=3, number=1000000)))
où les fonctions suivantes ont été testées
from re import match as re_match
from re import compile as re_compile
def is_number_tryexcept(s):
""" Returns True is string is a number. """
try:
float(s)
return True
except ValueError:
return False
def is_number_regex(s):
""" Returns True is string is a number. """
if re_match("^\d+?\.\d+?$", s) is None:
return s.isdigit()
return True
comp = re_compile("^\d+?\.\d+?$")
def compiled_regex(s):
""" Returns True is string is a number. """
if comp.match(s) is None:
return s.isdigit()
return True
def is_number_repl_isdigit(s):
""" Returns True is string is a number. """
return s.replace('.','',1).isdigit()
il y a une exception que vous pouvez prendre en compte: la chaîne "nan "
si vous voulez que IS_NUMBER retourne FALSE pour 'NaN' ce code ne fonctionnera pas car Python le convertit à sa représentation d'un nombre qui n'est pas un nombre (parlez des problèmes d'identité):
>>> float('NaN')
nan
sinon, je devrais vous remercier pour le morceau de code que j'utilise maintenant largement. :)
G.
que pensez-vous de ceci:
'3.14'.replace('.','',1).isdigit()
qui ne retournera vrai que s'il y en a un ou pas.""dans la chaîne de chiffres.
'3.14.5'.replace('.','',1).isdigit()
retournera false
edit: viens de voir un autre commentaire ...
ajouter un .replace(badstuff,'',maxnum_badstuff)
pour les autres cas peut être fait. si vous passez du sel et non des condiments arbitraires (réf: xkcd#974 ) cela fera très bien: p
mis à jour après que Alfe a souligné que vous n'avez pas besoin de vérifier pour flotteur séparément comme les poignées complexes à la fois:
def is_number(s):
try:
complex(s) # for int, long, float and complex
except ValueError:
return False
return True
précédemment dit: Est-ce que certains cas rares, vous pourriez aussi avoir besoin de vérifier des nombres complexes( par exemple 1+2i), qui ne peuvent pas être représentés par un flotteur:
def is_number(s):
try:
float(s) # for int, long and float
except ValueError:
try:
complex(s) # for complex
except ValueError:
return False
return True
qui, non seulement est laid et lent, semble grotesque.
cela peut prendre un peu de s'habituer, mais c'est la façon pythonique de le faire. Comme on l'a déjà souligné, les alternatives sont pires. Mais il y a un autre avantage à faire les choses de cette façon: le polymorphisme.
L'idée centrale de duck-typing est que "si ça marche et parle comme un canard, alors c'est un canard."Que faire si vous décidez que vous avez besoin de sous-classe chaîne de chaîne de sorte que vous pouvez changer comment vous déterminez si quelque chose peut être converti en un flotteur? Ou si vous décidez de tester un autre objet entièrement? Vous pouvez faire ces choses sans avoir à changer le code ci-dessus.
d'autres langues résolvent ces problèmes en utilisant des interfaces. Je garde l'analyse de la solution qui est meilleure pour un autre fil. Le point, cependant, est que python est décidément sur le côté canard Dactylographie de l'équation, et vous allez probablement devoir s'habituer à une syntaxe comme celle-ci si vous prévoyez de faire beaucoup de programmation en Python (mais cela ne veut pas dire que vous devez l'aimer bien sûr).
une autre chose que vous pourriez vouloir prendre en considération: Python est assez rapide dans le lancement et la capture d'exceptions par rapport à beaucoup d'autres langues (30x plus rapide que .Net par exemple). Zut, le langage lui-même jette même des exceptions pour communiquer non-exceptionnel, conditions normales de programme (chaque fois que vous utilisez un pour boucle.) Ainsi, Je ne m'inquiéterais pas trop des aspects de performance de ce code jusqu'à ce que vous remarquiez un problème important.
pour int
utilisez ceci:
>>> "1221323".isdigit()
True
Mais pour float
nous avons besoin de quelques trucs ;-). Chaque numéro de flotteur a un point...
>>> "12.34".isdigit()
False
>>> "12.34".replace('.','',1).isdigit()
True
>>> "12.3.4".replace('.','',1).isdigit()
False
pour les nombres négatifs, il suffit d'ajouter lstrip()
:
>>> '-12'.lstrip('-')
'12'
Et maintenant, nous obtenons un moyen universel:
>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False
pour les chaînes de non-nombres, try: except:
est en fait plus lent que les expressions régulières. Pour les chaînes de nombres valides, regex est plus lent. Donc, la méthode appropriée dépend de votre entrée.
si vous trouvez que vous êtes dans une performance bind, vous pouvez utiliser un nouveau module tiers appelé fastnumbers qui fournit une fonction appelée isfloat . La divulgation complète, je suis l'auteur. J'ai inclus ses résultats dans le temps ci-dessous.
from __future__ import print_function
import timeit
prep_base = '''\
x = 'invalid'
y = '5402'
z = '4.754e3'
'''
prep_try_method = '''\
def is_number_try(val):
try:
float(val)
return True
except ValueError:
return False
'''
prep_re_method = '''\
import re
float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
def is_number_re(val):
return bool(float_match(val))
'''
fn_method = '''\
from fastnumbers import isfloat
'''
print('Try with non-number strings', timeit.timeit('is_number_try(x)',
prep_base + prep_try_method), 'seconds')
print('Try with integer strings', timeit.timeit('is_number_try(y)',
prep_base + prep_try_method), 'seconds')
print('Try with float strings', timeit.timeit('is_number_try(z)',
prep_base + prep_try_method), 'seconds')
print()
print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
prep_base + prep_re_method), 'seconds')
print('Regex with integer strings', timeit.timeit('is_number_re(y)',
prep_base + prep_re_method), 'seconds')
print('Regex with float strings', timeit.timeit('is_number_re(z)',
prep_base + prep_re_method), 'seconds')
print()
print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
prep_base + 'from fastnumbers import isfloat'), 'seconds')
print()
Try with non-number strings 2.39108395576 seconds
Try with integer strings 0.375686168671 seconds
Try with float strings 0.369210958481 seconds
Regex with non-number strings 0.748660802841 seconds
Regex with integer strings 1.02021503448 seconds
Regex with float strings 1.08564686775 seconds
fastnumbers with non-number strings 0.174362897873 seconds
fastnumbers with integer strings 0.179651021957 seconds
fastnumbers with float strings 0.20222902298 seconds
comme vous pouvez voir
-
try: except:
était rapide pour une entrée numérique mais très lent pour une entrée invalide - regex est très efficace lorsque l'entrée n'est pas valide
-
fastnumbers
gagne dans les deux cas,
Seulement Imiter C#
dans C# il y a deux fonctions différentes qui gèrent l'analyse des valeurs scalaires:
- Float.Parse ()
- flotteur.TryParse ()
float.parse ():
def parse(string):
try:
return float(string)
except Exception:
throw TypeError
Note: Si vous vous demandez pourquoi j'ai changé l'exception à une erreur de frappe, voici le documentation .
float.try_parse ():
def try_parse(string, fail=None):
try:
return float(string)
except Exception:
return fail;
Note: Vous ne voulez pas retourner le booléen 'False' parce que c'est toujours un type de valeur. Aucun n'est meilleur parce qu'il indique l'échec. Bien sûr, si vous voulez quelque chose de différent, vous pouvez modifier l'échec de paramètre que vous voulez.
pour étendre le flotteur pour inclure le "parse ()" et 'try_parse () 'vous aurez besoin de la classe' float ' pour ajouter ces méthodes.
si vous voulez respecter les fonctions préexistantes, le code devrait ressembler à quelque chose comme:
def monkey_patch():
if(!hasattr(float, 'parse')):
float.parse = parse
if(!hasattr(float, 'try_parse')):
float.try_parse = try_parse
SideNote: personnellement, je préfère l'appeler Monkey Punching parce qu'il se sent comme j'abuse de la langue quand je fais ceci mais YMMV.
Utilisation:
float.parse('giggity') // throws TypeException
float.parse('54.3') // returns the scalar value 54.3
float.tryParse('twank') // returns None
float.tryParse('32.2') // returns the scalar value 32.2
et le grand sauge Pythonas a dit au Saint-Siège Sharpisus," Tout ce que vous pouvez faire je peux faire mieux; je peux faire tout mieux que vous."
je sais que c'est particulièrement ancien, mais je voudrais ajouter une réponse je crois couvre l'information manquante de la plus haute réponse votée qui pourrait être très utile à tous ceux qui trouvent cela:
Pour chacune des méthodes suivantes connecter avec un compte si vous avez besoin d'une entrée pour être accepté. (En supposant que nous utilisons des définitions vocales d'entiers plutôt que 0-255, etc.)
x.isdigit()
fonctionne bien pour vérifier si x est un entier.
x.replace('-','').isdigit()
fonctionne bien pour vérifier si x est négatif.(Arrivée en première position)
x.replace('.','').isdigit()
fonctionne bien pour vérifier si x est un nombre décimal.
x.replace(':','').isdigit()
fonctionne bien pour vérifier si x est un rapport.
x.replace('/','',1).isdigit()
fonctionne bien pour vérifier si x est une fraction.
Coulée flotter et attraper ValueError est probablement le moyen le plus rapide, depuis float() est spécifiquement conçu pour cela. Tout ce qui nécessite l'analyse de chaîne (regex, etc) sera probablement plus lent en raison du fait qu'il n'est pas accordé pour cette opération. Mon de 0,02$.
vous pouvez utiliser des chaînes Unicode, ils ont une méthode pour faire exactement ce que vous voulez:
>>> s = u"345"
>>> s.isnumeric()
True
ou:
>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True
je voulais voir quelle méthode est la plus rapide. Dans l'ensemble, la fonction check_replace
a donné les meilleurs résultats et les plus constants. Les résultats les plus rapides ont été donnés par la fonction check_exception
, mais seulement s'il n'y avait pas d'exception tirée - ce qui signifie que son code est le plus efficace, mais la hauteur de lancer une exception est assez grande.
s'il Vous Plaît noter que la vérification d'une coulée réussie est la seule méthode qui est précise, par exemple, cela fonctionne avec check_exception
mais les deux autres fonctions d'essai retourneront False pour un flotteur valide:
huge_number = float('1e+100')
voici le code de référence:
import time, re, random, string
ITERATIONS = 10000000
class Timer:
def __enter__(self):
self.start = time.clock()
return self
def __exit__(self, *args):
self.end = time.clock()
self.interval = self.end - self.start
def check_regexp(x):
return re.compile("^\d*\.?\d*$").match(x) is not None
def check_replace(x):
return x.replace('.','',1).isdigit()
def check_exception(s):
try:
float(s)
return True
except ValueError:
return False
to_check = [check_regexp, check_replace, check_exception]
print('preparing data...')
good_numbers = [
str(random.random() / random.random())
for x in range(ITERATIONS)]
bad_numbers = ['.' + x for x in good_numbers]
strings = [
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
for x in range(ITERATIONS)]
print('running test...')
for func in to_check:
with Timer() as t:
for x in good_numbers:
res = func(x)
print('%s with good floats: %s' % (func.__name__, t.interval))
with Timer() as t:
for x in bad_numbers:
res = func(x)
print('%s with bad floats: %s' % (func.__name__, t.interval))
with Timer() as t:
for x in strings:
res = func(x)
print('%s with strings: %s' % (func.__name__, t.interval))
Voici les résultats avec Python 2.7.10 sur un MacBook Pro 13 2017:
check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169
Voici les résultats avec Python 3.6.5 sur un MacBook Pro 13 2017:
check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002
Voici les résultats avec PyPy 2.7.13 sur un 2017 MacBook Pro 13:
check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056
disons que vous avez des chiffres dans la chaîne. str = " 100949" et vous aimeriez vérifier si elle a seulement des numéros
if str.isdigit():
returns TRUE or FALSE
sinon votre méthode fonctionne très bien pour trouver l'occurrence d'un caractère dans une chaîne.
cette réponse fournit un guide étape par étape ayant une fonction avec des exemples pour trouver la chaîne est:
- entier Positif
- Positif/négatif - entier/flottant
- Comment supprimer les chaînes " NaN " (pas un nombre) lors de la vérification du nombre?
vérifier si la chaîne est positif entier
vous pouvez utiliser str.isdigit()
pour vérifier si une chaîne de caractères donnée est positif entier.
Résultats De L'Échantillon:
# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False
Vérifier la chaîne de positif/négatif entier/flottant
str.isdigit()
renvoie False
si la chaîne est un négatif nombre ou un float nombre. Par exemple:
# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False
si vous voulez cochez également la case négatif entiers et float
, ensuite, vous pouvez écrire une fonction personnalisée pour vérifier qu'il est:
def is_number(n):
try:
float(n) # Type-casting the string to `float`.
# If string is not a valid `float`,
# it'll raise `ValueError` exception
except ValueError:
return False
return True
Exemple:
>>> is_number('123') # positive integer number
True
>>> is_number('123.4') # positive float number
True
>>> is_number('-123') # negative integer number
True
>>> is_number('-123.4') # negative `float` number
True
>>> is_number('abc') # `False` for "some random" string
False
jeter " NAN "(pas un nombre) chaînes lors de la vérification du nombre
les fonctions ci-dessus seront return True
pour la chaîne" NAN " (Not a number) car pour Python il est valide float représentant il n'est pas un nombre. Par exemple:
>>> is_number('NaN')
True
afin de vérifier si le nombre est "NaN", vous pouvez utiliser math.isnan()
comme:
>>> import math
>>> nan_num = float('nan')
>>> math.isnan(nan_num)
True
ou si vous ne voulez pas importer de bibliothèque supplémentaire pour vérifier cela, alors vous pouvez simplement le vérifier en le comparant avec lui-même en utilisant ==
. Python renvoie False
quand nan
est comparé avec lui-même. Par exemple:
# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False
donc, au-dessus de fonction is_number
peut être mis à jour pour retourner False
pour "NaN"
comme:
def is_number(n):
is_number = True
try:
num = float(n)
# check for "nan" floats
is_number = num == num # or use `math.isnan(num)`
except ValueError:
is_number = False
return is_number
Exemple:
>>> is_number('Nan') # not a number "Nan" string
False
>>> is_number('nan') # not a number string "nan" with all lower cased
False
>>> is_number('123') # positive integer
True
>>> is_number('-123') # negative integer
True
>>> is_number('-1.12') # negative `float`
True
>>> is_number('abc') # "some random" string
False
PS: chaque opération pour chaque contrôle en fonction du type de nombre vient avec supplémentaire généraux. Choisissez la version de la fonction is_number
qui correspond à vos besoins.
donc pour le mettre ensemble, en vérifiant pour Nan, infini et nombres complexes (il semblerait qu'ils sont spécifiés avec j, pas i, i.e. 1+2j) il résulte en:
def is_number(s):
try:
n=str(float(s))
if n == "nan" or n=="inf" or n=="-inf" : return False
except ValueError:
try:
complex(s) # for complex
except ValueError:
return False
return True
votre code me semble correct.
peut-être pensez-vous que le code est "clunky" à cause de l'utilisation d'exceptions? Notez que les programmeurs Python ont tendance à utiliser les exceptions de façon libérale quand cela améliore la lisibilité du code, grâce à sa faible performance pénalité.
j'ai fait un test de vitesse. Disons que si la chaîne de caractères est probable pour être un numéro, la stratégie try/except est la plus rapide possible.Si la chaîne est pas susceptible d'être un nombre et vous êtes intéressé par entier vérifier, il vaut la peine de faire un certain test (isdigit plus heading '-'). Si vous êtes intéressé à vérifier le nombre de flotteurs, vous devez utiliser le essayer / sauf code sans s'échapper.
je devais déterminer si une corde moulée dans les types de base (float,int,str,bool). Après n'avoir rien trouvé sur internet, j'ai créé ceci:
def str_to_type (s):
""" Get possible cast type for a string
Parameters
----------
s : string
Returns
-------
float,int,str,bool : type
Depending on what it can be cast to
"""
try:
f = float(s)
if "." not in s:
return int
return float
except ValueError:
value = s.upper()
if value == "TRUE" or value == "FALSE":
return bool
return type(s)
exemple
str_to_type("true") # bool
str_to_type("6.0") # float
str_to_type("6") # int
str_to_type("6abc") # str
str_to_type(u"6abc") # unicode
, Vous pouvez capturer le type et l'utiliser
s = "6.0"
type_ = str_to_type(s) # float
f = type_(s)
suggère RyanN
si vous voulez retourner False pour un NaN et Inf, changez la ligne en x = float(s); return (x == x) et (x - 1 != x). Cela devrait être vrai pour tous les flotteurs sauf Inf et NaN
mais cela ne fonctionne pas tout à fait, parce que pour des flotteurs suffisamment grands, x-1 == x
retourne vrai. Par exemple, 2.0**54 - 1 == 2.0**54
l'entrée peut être la suivante:
a="50"
b=50
c=50.1
d="50.1"
1-Entrée générale:
L'entrée de cette fonction peut être tout!
trouve si la variable donnée est numérique. Les chaînes numériques se composent du signe optionnel, de n'importe quel nombre de chiffres, de la partie décimale optionnelle et de la partie exponentielle optionnelle. + 0123.45e6 est une valeur numérique valide. La notation hexadécimale (par exemple 0xf4c3b00c) et binaire (par exemple 0b10100111001) n'est pas autorisée.
is_numeric fonction
import ast
import number
def is_numeric(obj):
if isinstance(obj, numbers.Number):
return True
elif isinstance(obj, str):
nodes = list(ast.walk(ast.parse(obj)))[1:]
if not isinstance(nodes[0], ast.Expr):
return False
if not isinstance(nodes[-1], ast.Num):
return False
nodes = nodes[1:-1]
for i in range(len(nodes)):
#if used + or - in digit :
if i % 2 == 0:
if not isinstance(nodes[i], ast.UnaryOp):
return False
else:
if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
return False
return True
else:
return False
test:
>>> is_numeric("54")
True
>>> is_numeric("54.545")
True
>>> is_numeric("0x45")
True
is_float fonction
trouve si la variable donnée est flottante. flotteur de chaînes se composent d'un signe optionnel, un nombre quelconque de chiffres ...
import ast
def is_float(obj):
if isinstance(obj, float):
return True
if isinstance(obj, int):
return False
elif isinstance(obj, str):
nodes = list(ast.walk(ast.parse(obj)))[1:]
if not isinstance(nodes[0], ast.Expr):
return False
if not isinstance(nodes[-1], ast.Num):
return False
if not isinstance(nodes[-1].n, float):
return False
nodes = nodes[1:-1]
for i in range(len(nodes)):
if i % 2 == 0:
if not isinstance(nodes[i], ast.UnaryOp):
return False
else:
if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
return False
return True
else:
return False
test:
>>> is_float("5.4")
True
>>> is_float("5")
False
>>> is_float(5)
False
>>> is_float("5")
False
>>> is_float("+5.4")
True
qu'est-ce que ast ?
2- Si vous êtes sûr que le contenu de la variable est chaîne de caractères :
utiliser str.appel isdigit() méthode
>>> a=454
>>> a.isdigit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'
>>> a="454"
>>> a.isdigit()
True
3-Entrée numérique:
détecter int valeur:
>>> isinstance("54", int)
False
>>> isinstance(54, int)
True
>>>
détecter flotteur:
>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True
j'ai aussi utilisé la fonction que vous avez mentionnée, mais bientôt je remarque que les chaînes comme" Nan"," Inf " et sa variation sont considérées comme nombre. Je vous propose donc une version améliorée de votre fonction, qui retournera false sur ce type d'entrée et ne manquera pas de variantes "1E3":
def is_float(text):
try:
float(text)
# check for nan/infinity etc.
if text.isalpha():
return False
return True
except ValueError:
return False
si vous voulez savoir si la chaîne entière peut être représentée comme un nombre, vous voudrez utiliser un regexp (ou peut-être convertir le flotteur en une chaîne et le comparer à la chaîne source, mais je devine que ce n'est pas très rapide).
Voici ma façon simple de le faire. Disons que je suis en boucle sur certaines chaînes et je veux les ajouter à un tableau si elles se révèlent être des nombres.
try:
myvar.append( float(string_to_check) )
except:
continue
remplacer la myvar.apppend avec n'importe quelle opération que vous voulez faire avec la chaîne si elle s'avère être un nombre. L'idée est d'essayer d'utiliser un float() le fonctionnement et l'utilisation de l'a renvoyé l'erreur de déterminer si la chaîne est un nombre.
vous pouvez généraliser la technique d'exception d'une manière utile en retournant des valeurs plus utiles que True et False. Par exemple cette fonction met des guillemets autour des chaînes mais laisse les nombres seuls. Ce qui est exactement ce dont j'avais besoin pour un filtre rapide et sale pour faire quelques définitions variables pour R.
import sys
def fix_quotes(s):
try:
float(s)
return s
except ValueError:
return '"{0}"'.format(s)
for line in sys.stdin:
input = line.split()
print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'
je travaillais sur un problème qui m'a conduit à ce fil, à savoir comment convertir une collection de données en chaînes et numéros de la manière la plus intuitive. J'ai réalisé après avoir lu le code original que ce dont j'avais besoin était différent de deux façons:
1-je voulais un résultat entier si la chaîne représentait un entier
2 - je voulais un nombre ou un résultat de chaîne de caractères pour coller dans une structure de données
donc j'ai adapté l'original code pour produire ce dérivé:
def string_or_number(s):
try:
z = int(s)
return z
except ValueError:
try:
z = float(s)
return z
except ValueError:
return s
essayez ceci.
def is_number(var):
try:
if var == int(var):
return True
except Exception:
return False
import re
def is_number(num):
pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
result = pattern.match(num)
if result:
return True
else:
return False
>>>: is_number('1')
True
>>>: is_number('111')
True
>>>: is_number('11.1')
True
>>>: is_number('-11.1')
True
>>>: is_number('inf')
False
>>>: is_number('-inf')
False
utiliser la suite il traite tous les cas: -
import re
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.3')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '.3')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.3sd')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.3')