How can I tell when a string is in fact a number?

Alex Martelli aleaxit at yahoo.com
Mon Nov 6 15:50:26 CET 2000

```"Christian Tismer" <tismer at tismer.com> writes...:

> I'd like to know what is faster: One of these string.translate
> variations, or the new SRE engine?

They're pretty fast!  Here's my setup...:

import re, string

all_digits=re.compile(r'\d*\$')
any_non_digit=re.compile(r'[^0-9]')

def isanum1(str):
return all_digits.match(str) != None

def isanum2(str):
return any_non_digit.search(str) == None

# snipped slower ones

tlator = ["n"]*256
tlator[ord("0"):ord("9")+1] = [" "]*10
tlator = string.join(tlator, "")

def isanum6(s):
return len(string.split(string.translate(s, tlator))) == 0

tlator2=string.maketrans("","") # identity mapping

def isanum7(s):
return len(string.translate(s, tlator2, "0123456789")) == 0

digs80 = string.digits*80
digsax = digs80 + 'x'

import time

def dotest(function, string, repetitions=1000):
start = time.clock()
for i in range(repetitions):
function(string)
end = time.clock()
print "%6.3f secs" % (end-start)

import profile

def test(funnum, strname='digs80', repetitions=1000):
funname = "isanum%d" % funnum
funob = eval(funname)
strob = eval(strname)
print "%s(%s):" % (funname,strname),
dotest(funob,strob,repetitions)

And here a few results (pretty repeatable ones) --
first, when str is 80 digits:

>>> aldig.test(1)
isanum1(digs80):  0.094 secs
>>> aldig.test(2)
isanum2(digs80):  0.155 secs
>>> aldig.test(6)
isanum6(digs80):  0.123 secs
>>> aldig.test(7)
isanum7(digs80):  0.045 secs

(for some reason, in this way, I get about 95 vs
150 msec for isanum1 and isanum2; previously, with
profile.run, I was seeing about 70 ms for either [?]).

then, when str is 80 digits then a non-digit:

>>> aldig.test(1, 'digsax')
isanum1(digsax):  0.252 secs
>>> aldig.test(2, 'digsax')
isanum2(digsax):  0.165 secs
>>> aldig.test(6, 'digsax')
isanum6(digsax):  0.127 secs
>>> aldig.test(7, 'digsax')
isanum7(digsax):  0.045 secs

Alex

```