Si le importaba el rendimiento (y no estoy sugiriendo que debería hacerlo), el enfoque basado en intentos es el claro ganador (en comparación con su enfoque basado en particiones o el enfoque regexp), siempre que no espere mucho cadenas no válidas, en cuyo caso es potencialmente más lento (presumiblemente debido al costo del manejo de excepciones).
Nuevamente, no estoy sugiriendo que se preocupe por el rendimiento, solo le doy los datos en caso de que esté haciendo esto 10 mil millones de veces por segundo, o algo así. Además, el código basado en particiones no maneja al menos una cadena válida.
$ ./floatstr.py
F..
partición triste: 3.1102449894
partición feliz: 2.09208488464
..
re triste: 7.76906108856
re feliz: 7.09421992302
..
prueba triste: 12.1525540352
intenta feliz: 1.44165301323
.
================================================== ====================
FAIL: test_partition (__main __. ConvertTests)
-------------------------------------------------- --------------------
Rastreo (llamadas recientes más última):
Archivo "./floatstr.py", línea 48, en test_partition
self.failUnless (is_float_partition ("20e2"))
AserciónError
-------------------------------------------------- --------------------
Ran 8 pruebas en 33.670s
FALLIDO (fallas = 1)
Aquí está el código (Python 2.6, regexp tomado de la respuesta de John Gietzen ):
def is_float_try(str):
try:
float(str)
return True
except ValueError:
return False
import re
_float_regexp = re.compile(r"^[-+]?(?:\b[0-9]+(?:\.[0-9]*)?|\.[0-9]+\b)(?:[eE][-+]?[0-9]+\b)?$")
def is_float_re(str):
return re.match(_float_regexp, str)
def is_float_partition(element):
partition=element.partition('.')
if (partition[0].isdigit() and partition[1]=='.' and partition[2].isdigit()) or (partition[0]=='' and partition[1]=='.' and pa\
rtition[2].isdigit()) or (partition[0].isdigit() and partition[1]=='.' and partition[2]==''):
return True
if __name__ == '__main__':
import unittest
import timeit
class ConvertTests(unittest.TestCase):
def test_re(self):
self.failUnless(is_float_re("20e2"))
def test_try(self):
self.failUnless(is_float_try("20e2"))
def test_re_perf(self):
print
print 're sad:', timeit.Timer('floatstr.is_float_re("12.2x")', "import floatstr").timeit()
print 're happy:', timeit.Timer('floatstr.is_float_re("12.2")', "import floatstr").timeit()
def test_try_perf(self):
print
print 'try sad:', timeit.Timer('floatstr.is_float_try("12.2x")', "import floatstr").timeit()
print 'try happy:', timeit.Timer('floatstr.is_float_try("12.2")', "import floatstr").timeit()
def test_partition_perf(self):
print
print 'partition sad:', timeit.Timer('floatstr.is_float_partition("12.2x")', "import floatstr").timeit()
print 'partition happy:', timeit.Timer('floatstr.is_float_partition("12.2")', "import floatstr").timeit()
def test_partition(self):
self.failUnless(is_float_partition("20e2"))
def test_partition2(self):
self.failUnless(is_float_partition(".2"))
def test_partition3(self):
self.failIf(is_float_partition("1234x.2"))
unittest.main()