What is the best possible way to check if a string can be represented as a number in Python?
The function I currently have right now is:
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
Which, not only is ugly and slow, seems clunky. However I haven't found a better method because calling float
in the main function is even worse.
This code handles the exponents, floats, and integers, wihtout using regex.
If you want to know if the entire string can be represented as a number you'll want to use a regexp (or maybe convert the float back to a string and compare it to the source string, but I'm guessing that's not very fast).
Updated after Alfe pointed out you don't need to check for float separately as complex handles both:
Previously said: Is some rare cases you might also need to check for complex numbers (e.g. 1+2i), which can not be represented by a float:
I know this is particularly old but I would add an answer I believe covers the information missing from the highest voted answer that could be very valuable to any who find this:
For each of the following methods connect them with a count if you need any input to be accepted. (Assuming we are using vocal definitions of integers rather than 0-255, etc.)
x.isdigit()
works well for checking if x is an integer.x.replace('-','').isdigit()
works well for checking if x is a negative.(Check - in first position)x.replace('.','').isdigit()
works well for checking if x is a decimal.x.replace(':','').isdigit()
works well for checking if x is a ratio.x.replace('/','',1).isdigit()
works well for checking if x is a fraction.The input may be as follows:
a="50"
b=50
c=50.1
d="50.1"
1-General input:
The input of this function can be everything!
Finds whether the given variable is numeric. Numeric strings consist of optional sign, any number of digits, optional decimal part and optional exponential part. Thus +0123.45e6 is a valid numeric value. Hexadecimal (e.g. 0xf4c3b00c) and binary (e.g. 0b10100111001) notation is not allowed.
is_numeric function
test:
is_float function
Finds whether the given variable is float. float strings consist of optional sign, any number of digits, ...
test:
what is ast?
2- If you are confident that the variable content is String:
use str.isdigit() method
3-Numerical input:
detect int value:
detect float:
It may take some getting used to, but this is the pythonic way of doing it. As has been already pointed out, the alternatives are worse. But there is one other advantage of doing things this way: polymorphism.
The central idea behind duck typing is that "if it walks and talks like a duck, then it's a duck." What if you decide that you need to subclass string so that you can change how you determine if something can be converted into a float? Or what if you decide to test some other object entirely? You can do these things without having to change the above code.
Other languages solve these problems by using interfaces. I'll save the analysis of which solution is better for another thread. The point, though, is that python is decidedly on the duck typing side of the equation, and you're probably going to have to get used to syntax like this if you plan on doing much programming in Python (but that doesn't mean you have to like it of course).
One other thing you might want to take into consideration: Python is pretty fast in throwing and catching exceptions compared to a lot of other languages (30x faster than .Net for instance). Heck, the language itself even throws exceptions to communicate non-exceptional, normal program conditions (every time you use a for loop). Thus, I wouldn't worry too much about the performance aspects of this code until you notice a significant problem.