isFloat: Without Exception-Handling
Mark McEahern
marklists at mceahern.com
Fri Sep 20 10:15:55 EDT 2002
[Magnus Lycka]
> Something like this perhaps:
>
> import re
>
> def isFloat(S):
> floatRE = r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$"
> return re.match(floatRE, str(S)) is not None
>
> I'm not sure it's faster though.
If you were going to run this lots of times, you might want to compile the
pattern. Anyway, the exception based code is faster, by my testing (harness
at bottom):
isFloatExcept 0.220
isFloatRE 0.521
isFloatRECompiled 0.400
Again, I wonder, why avoid the exception test?
Cheers,
// mark
Harness:
#!/usr/bin/env python
import re
from time import clock
# Compile up front.
floatPattern = re.compile(r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$")
def isFloatExcept(s):
is_float = True
try:
float(s)
except (ValueError, TypeError), e:
is_float = False
return is_float
def isFloatRE(s):
floatRE = r"^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$"
return re.match(floatRE, str(s)) is not None
def isFloatRECompiled(s):
return floatPattern.match(str(s)) is not None
def time_it(fn, test_data, n):
time_in = clock()
for x in xrange(n):
for (s, expected) in test_data:
actual = fn(s)
assert actual == expected
time_out = clock()
return time_out - time_in
def show(fn, r):
print "%20s %1.3f" % (fn.func_name, r)
def test():
test_data = [(1.2, True),
(1, True),
(-1, True),
(1e+10, True),
("1e-10", True),
("banana", False),
("5j", False),
(4+0j, False),
(isFloatExcept, False),
(__import__, False),
(clock, False)]
n = 1000
results = {}
for fn in (isFloatExcept, isFloatRE, isFloatRECompiled):
r = time_it(fn, test_data, n)
results[fn] = r
for fn in results:
show(fn, results[fn])
if __name__ == "__main__":
test()
-
More information about the Python-list
mailing list