Existe-t-il un moyen de savoir si une chaîne représente un entier (par exemple, '3'
, '-17'
mais pas '3.14'
ou 'asfasfas'
) Sans utiliser un mécanisme try / except?
is_int('3.14') = False
is_int('-7') = True
Existe-t-il un moyen de savoir si une chaîne représente un entier (par exemple, '3'
, '-17'
mais pas '3.14'
ou 'asfasfas'
) Sans utiliser un mécanisme try / except?
is_int('3.14') = False
is_int('-7') = True
avec des entiers positifs, vous pourriez utiliser `` :
il ne fonctionne pas avec des entiers négatifs cependant. Supposons que vous pourriez essayer ce qui suit :
ça ne marchera pas avec format, qui est semblable à
coulée en ce sens.
edit:
Vous savez, j'ai trouvé (et j'ai testé cela sur et plus) qui try/except ne pas effectuer aussi bien, pour quelque raison que ce soit. J'ai souvent essayer plusieurs façons de faire les choses, et je ne pense pas que je n'ai jamais trouvé une méthode qui utilise des try/except pour effectuer le meilleur de ceux testés, en fait il me semble que ces méthodes aient sortent généralement à proximité de la pire des, si pas le pire. Pas dans tous les cas, mais dans de nombreux cas. Je sais que beaucoup de gens disent que c'est la "Pythonic", mais c'est un domaine où j'ai fait partie des manières avec eux. Pour moi, c'est ni très puissant ni très élégant, donc, j'ai tendance à ne les utiliser que pour la récupération d'erreur et le reporting.
J'allais reproche que PHP, perl, ruby, C, et même le flipper shell ont des fonctions simples pour tester une chaîne de caractères pour l'entier le capot, mais de diligence raisonnable dans la vérification de ces hypothèses déclenché moi! Apparemment, ce manque est une commune de la maladie.
Voici un moyen rapide et sale édition de Richard post:
import sys, time, re
g_intRegex = re.compile(r"[-+]?\d+(\.0*)?$")
testvals = [
# integers
0, 1, -1, 1.0, -1.0,
'0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0', '06',
# non-integers
1.1, -1.1, '1.1', '-1.1', '+1.1',
'1.1.1', '1.1.0', '1.0.1', '1.0.0',
'1.0.', '1..0', '1..',
'0.0.', '0..0', '0..',
'one', object(), (1,2,3), [1,2,3], {'one':'two'},
# with spaces
' 0 ', ' 0.', ' .0','.01 '
]
def isInt_try(v):
try: i = int(v)
except: return False
return True
def isInt_str(v):
v = str(v).strip()
return v=='0' or (v if v.find('..') > -1 else v.lstrip('-+').rstrip('0').rstrip('.')).isdigit()
def isInt_re(v):
import re
if not hasattr(isInt_re, 'intRegex'):
isInt_re.intRegex = re.compile(r"[-+]?\d+(\.0*)?$")
return isInt_re.intRegex.match(str(v).strip()) is not None
def isInt_re2(v):
return g_intRegex.match(str(v).strip()) is not None
def timeFunc(func, times):
t1 = time.time()
for n in xrange(times):
for v in testvals:
r = func(v)
t2 = time.time()
return t2 - t1
def testFuncs(funcs):
for func in funcs:
sys.stdout.write( "\t%s\t|" % func.__name__)
print
for v in testvals:
sys.stdout.write("%s" % str(v))
for func in funcs:
sys.stdout.write( "\t\t%s\t|" % func(v))
print
if __name__ == '__main__':
print
print "tests.."
testFuncs((isInt_try, isInt_str, isInt_re, isInt_re2))
print
print "timings.."
print "isInt_try: %6.4f" % timeFunc(isInt_try, 10000)
print "isInt_str: %6.4f" % timeFunc(isInt_str, 10000)
print "isInt_re: %6.4f" % timeFunc(isInt_re, 10000)
print "isInt_re2: %6.4f" % timeFunc(isInt_re2, 10000)
Voici la partie intéressante de la sortie:
timings..
isInt_try: 1.2454
isInt_str: 0.7878
isInt_re: 1.5731
isInt_re2: 0.8087
Comme vous pouvez le voir, la méthode de chaîne est la plus rapide. Il est presque deux fois plus rapide que la regex méthode qui évite de se fonder sur des variables globales, et plus d'une fois et demie plus vite que le coup d'essayer:à l'exception de la méthode. La regex méthode qui repose sur certains globals (ou attributs de module) est une seconde près.
Je pense à ces choses, mon choix serait
isInt = isInt_str
Mais hein.. c'est de la copie et recopie et de recopier l'intégralité de la chaîne! (Et pourtant c'est la méthode la plus rapide!?) Un C méthode d'analyse une Fois, et d'être fait. Un C méthode qui analyse la chaîne de caractères une fois serait la bonne Chose à faire, je pense? Je suppose qu'il pourrait y avoir une chaîne de codage des questions à traiter.. de toute façon, je vais l'essayer et de travailler un moment, mais je n'ai pas le temps pour cela. =( Je vais peut-être y revenir plus tard.
La bonne RegEx solution serait de combiner les idées de Greg Hewgill et Nowell, mais ne pas utiliser une variable globale. Vous pouvez accomplir cela en attachant un attribut de la méthode. Aussi, je sais que c'est mal vu de mettre les importations dans une méthode, mais ce que je vais faire est un "paresseux module" effet comme http://peak.telecommunity.com/DevCenter/Importing#lazy-imports
edit: Mon préféré pour l'instant est d'utiliser exclusivement des méthodes de l'objet String.
#!/usr/bin/env python
def isInteger(i):
i = str(i)
return i=='0' or (i if i.find('..') > -1 else i.lstrip('-+').rstrip('0').rstrip('.')).isdigit()
def isIntegre(i):
import re
if not hasattr(isIntegre, '_re'):
print "I compile only once. Remove this line when you are confedent in that."
isIntegre._re = re.compile(r"[-+]?\d+(\.0*)?$")
return isIntegre._re.match(str(i)) is not None
# When executed directly run Unit Tests
if __name__ == '__main__':
for o in [
# integers
0, 1, -1, 1.0, -1.0,
'0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0',
# non-integers
1.1, -1.1, '1.1', '-1.1', '+1.1',
'1.1.1', '1.1.0', '1.0.1', '1.0.0',
'1.0.', '1..0', '1..',
'0.0.', '0..0', '0..',
'one', object(), (1,2,3), [1,2,3], {'one':'two'}
]:
# Notice the integre uses 're' (intended to be humorous)
integer = ('an integer' if isInteger(o) else 'NOT an integer')
integre = ('an integre' if isIntegre(o) else 'NOT an integre')
if isinstance(o, str):
print "%s is %s is %s" % (("'%s'" % (o,)), integer, integre)
else:
print "%s is %s is %s" % (o, integer, integre)
Et pour les moins aventureux, membre de la classe, voici le résultat:
I compile only once. Remove this line when you are confedent in that.
0 is an integer is an integre
1 is an integer is an integre
-1 is an integer is an integre
1.0 is an integer is an integre
-1.0 is an integer is an integre
'0' is an integer is an integre
'0.' is an integer is an integre
'0.0' is an integer is an integre
'1' is an integer is an integre
'-1' is an integer is an integre
'+1' is an integer is an integre
'1.0' is an integer is an integre
'-1.0' is an integer is an integre
'+1.0' is an integer is an integre
1.1 is NOT an integer is NOT an integre
-1.1 is NOT an integer is NOT an integre
'1.1' is NOT an integer is NOT an integre
'-1.1' is NOT an integer is NOT an integre
'+1.1' is NOT an integer is NOT an integre
'1.1.1' is NOT an integer is NOT an integre
'1.1.0' is NOT an integer is NOT an integre
'1.0.1' is NOT an integer is NOT an integre
'1.0.0' is NOT an integer is NOT an integre
'1.0.' is NOT an integer is NOT an integre
'1..0' is NOT an integer is NOT an integre
'1..' is NOT an integer is NOT an integre
'0.0.' is NOT an integer is NOT an integre
'0..0' is NOT an integer is NOT an integre
'0..' is NOT an integer is NOT an integre
'one' is NOT an integer is NOT an integre
<object object at 0xb786c4b8> is NOT an integer is NOT an integre
(1, 2, 3) is NOT an integer is NOT an integre
[1, 2, 3] is NOT an integer is NOT an integre
{'one': 'two'} is NOT an integer is NOT an integre
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.