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 answer provides step by step guide having function with examples to find the string is:
Check if string is positive integer
You may use
str.isdigit()
to check whether given string is positive integer.Sample Results:
Check for string as positive/negative - integer/float
str.isdigit()
returnsFalse
if the string is a negative number or a float number. For example:If you want to also check for the negative integers and
float
, then you may write a custom function to check for it as:Sample Run:
Discard "NaN" (not a number) strings while checking for number
The above functions will return
True
for the "NAN" (Not a number) string because for Python it is valid float representing it is not a number. For example:In order to check whether the number is "NaN", you may use
math.isnan()
as:Or if you don't want to import additional library to check this, then you may simply check it via comparing it with itself using
==
. Python returnsFalse
whennan
float is compared with itself. For example:Hence, above function
is_number
can be updated to returnFalse
for"NaN"
as:Sample Run:
PS: Each operation for each check depending on the type of number comes with additional overhead. Choose the version of
is_number
function which fits your requirement.TL;DR The best solution is
s.replace('.','',1).isdigit()
I did some benchmarks comparing the different approaches
If the string is not a number, the except-block is quite slow. But more importantly, the try-except method is the only approach that handles scientific notations correctly.
Float notation ".1234" is not supported by:
- is_number_regex
Scientific notation "1.000000e+50" is not supported by:
- is_number_regex
- is_number_repl_isdigit
Scientific notation "1e50" is not supported by:
- is_number_regex
- is_number_repl_isdigit
EDIT: The benchmark results
where the following functions were tested
Lets say you have digits in string. str = "100949" and you would like to check if it has only numbers
isdigit docs
otherwise your method works great to find the occurrence of a digit in a string.
how about this:
which will return true only if there is one or no '.' in the string of digits.
will return false
edit: just saw another comment ... adding a
.replace(badstuff,'',maxnum_badstuff)
for other cases can be done. if you are passing salt and not arbitrary condiments (ref:xkcd#974) this will do fine :PJust Mimic C#
In C# there are two different functions that handle parsing of scalar values:
float.parse():
Note: If you're wondering why I changed the exception to a TypeError, here's the documentation.
float.try_parse():
Note: You don't want to return the boolean 'False' because that's still a value type. None is better because it indicates failure. Of course, if you want something different you can change the fail parameter to whatever you want.
To extend float to include the 'parse()' and 'try_parse()' you'll need to monkeypatch the 'float' class to add these methods.
If you want respect pre-existing functions the code should be something like:
SideNote: I personally prefer to call it Monkey Punching because it feels like I'm abusing the language when I do this but YMMV.
Usage:
And the great Sage Pythonas said to the Holy See Sharpisus, "Anything you can do I can do better; I can do anything better than you."
I needed to determine if a string cast into basic types (float,int,str,bool). After not finding anything on the internet I created this:
Example
You can capture the type and use it