4

Is there a quick way to find if a string is a real number, short of reading it a character at a time and doing isdigit() on each character? I want to be able to test floating point numbers, for example 0.03001.

jscs
  • 63,694
  • 13
  • 151
  • 195
Illusionist
  • 5,204
  • 11
  • 46
  • 76
  • 3
    Define "a real number". Integer or floating point? Signed or unsigned? etc. –  May 10 '11 at 20:45
  • I'm pretty sure that the question meant [real number](https://en.wikipedia.org/wiki/Real_number) in the mathematical sense. – Karl Knechtel Jan 24 '23 at 17:52

7 Answers7

14

If you mean an float as a real number this should work:

def isfloat(str):
    try: 
        float(str)
    except ValueError: 
        return False
    return True

Note that this will internally still loop your string, but this is inevitable.

wim
  • 338,267
  • 99
  • 616
  • 750
orlp
  • 112,504
  • 36
  • 218
  • 315
  • thanks but i need to do floats, so i guess i could replace the try:int(str) with try:float(str) ? – Illusionist May 10 '11 at 20:50
  • 2
    *caveat*: Don't use a blanket `except` clause! That's a dangerous bad practice. Catch `ValueError` explicitly. – Santa May 10 '11 at 20:55
  • 3
    @Illusionist: When you tried replacing `int(str)` with `float(str)` what did you observe? Did you know that you are allowed to try code on your own? – S.Lott May 10 '11 at 21:59
  • Now that the code is testing for floats rather than ints, it would be good to change the function name :) – ncoghlan May 11 '11 at 03:12
8
>>> a = "12345" # good number
>>> int(a)
12345
>>> b = "12345G" # bad number
>>> int(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '12345G'

You can do that:

def isNumber(s):
    try:
        int(s)
    except ValueError:
        return False
    return True

If you want a float number, replace int by float (thanks to @cobbal).

bfontaine
  • 18,169
  • 13
  • 73
  • 107
  • 2
    and if you want to test for floats, replace `int` with `float` – cobbal May 10 '11 at 20:51
  • Perhaps you should use "load new answers" next time, since this is an EXACT copy of my answer. – orlp May 10 '11 at 20:52
  • @nightcracker not really exact, I made an example. – bfontaine May 10 '11 at 20:54
  • 1
    Don't use a blanket `except` clause! That's a dangerous bad practice. Catch `ValueError` explicitly. – Santa May 10 '11 at 20:55
  • 1
    @nightcracker, the 'load new answers' bar sometimes takes minutes to appear after a new answer has been posted (for me, at least). I think you should give boudou the benefit of the doubt. – senderle May 10 '11 at 21:01
1

There is also another way using regular expression:

import re

def is_float(str):
    if re.match(r"\d+\.*\d*", str):
        return True
    else:
        return False
Thai Tran
  • 9,815
  • 7
  • 43
  • 64
1

There is a more precise regexp of the real numbers:

"^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$"

And some check for this regexp:

realnum=re.compile("^[-+]?[0-9]*\.?[0-9]+(e[-+]?[0-9]+)?$")

["yes" if realnum.match(test) else "no" for test in ["12", "+12", "-12", "-3.14", ".314e1", "+.01e-12", "+22.134e+2"]]
['yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes']

["yes" if realnum.match(test) else "no" for test in ["..12", "+-12", "-12.", "-3.14p", ".314e1.9", "+. 01e-12", "+22.134e"]]
['no', 'no', 'no', 'no', 'no', 'no', 'no']
0

Method to verify real number:

def verify_real_number(item):
""" Method to find if an 'item'is real number"""

item = str(item).strip()
if not(item):
    return False
elif(item.isdigit()):
    return True
elif re.match(r"\d+\.*\d*", item) or re.match(r"-\d+\.*\d*", item):
    return True
else:
    return False
Shailendra
  • 431
  • 5
  • 14
0

Defining a function to do this is the right approach, although it's a shame that Python does not already provide such a function.

I'm not a fan of using try ... except for this, because it was drilled into me that "exceptions are for exceptional circumstances", and not for control flow.

A one-line solution (if you ever want it, although it is less efficient, except for the regex answers) is

lambda x: all(n < 2 and i.isdigit() for n, i in enumerate(x.split('.')))

If you are going to encounter decimals written as 1. or .01, then simply add a length check

lambda x: all(n < 2 and (i.isdigit() or len(i) == 0) for n, i in enumerate(x.split('.')))
phantom-99w
  • 928
  • 1
  • 11
  • 22
0

if you wanna check both integer and float numbers, you can check this out

def isDigit(str):
    try:
        int(str) or float(str)
    except ValueError:
        return False
    return True
  • `isDigit()` raises a ValueError since `int()` raises a ValueError. @orlp's answer made 11 years ago is still valid. – david Aug 22 '22 at 14:34