How do I check if a string represents a number (float or int) in Python?

To determine if a string represents a numeric value (integer or float) in Python, you can use the following approaches. Each method addresses edge cases like leading/trailing whitespace, scientific notation (e.g., 1e3), and special values like NaN or Inf.

1. Using Exception Handling (Recommended)

Attempt to convert the string to a float and catch errors. This handles most valid numeric formats:

def is_number(s):
    try:
        s = s.strip()  # Remove leading/trailing whitespace
        if not s:
            return False  # Empty string after stripping
        num = float(s)
        # Optional: Exclude NaN/Inf (uncomment to disable)
        # if math.isnan(num) or math.isinf(num):
        #     return False
        return True
    except ValueError:
        return False

Example Usage:

print(is_number("123"))        # True (int)
print(is_number("-123.45"))    # True (float)
print(is_number("1e3"))        # True (scientific notation)
print(is_number(" 123.45 "))   # True (whitespace stripped)
print(is_number("NaN"))        # True (by default; returns False if uncommented)
print(is_number("12a3"))       # False
print(is_number(""))           # False

2. Using Regular Expressions

Match numeric patterns (integers, floats, scientific notation) with a regex. This avoids exceptions but requires precise pattern definition:

import re

def is_number_regex(s):
    pattern = r"^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$"
    return bool(re.fullmatch(pattern, s.strip()))

Regex Breakdown:

  • ^[+-]?: Optional leading + or -.
  • \d+\.?\d*: Matches integers (123) or floats with digits before the decimal (123., 123.45).
  • |\.\d+: Matches floats starting with . (e.g., .45).
  • (?:[eE][+-]?\d+)?$: Optional scientific notation (e.g., 1e3, -2.5E-4).

Example Usage:

print(is_number_regex("123"))      # True
print(is_number_regex(".45"))      # True
print(is_number_regex("123.45"))   # True
print(is_number_regex("1e3"))      # True
print(is_number_regex("12a3"))     # False
print(is_number_regex("NaN"))      # False (regex excludes non-numeric strings)

Key Differences

MethodProsCons
Exception HandlingHandles all valid Python numeric formats.Allows NaN/Inf by default.
RegexExplicit control over valid patterns.Complex regex; may miss edge cases.

Handling Integers vs. Floats

To distinguish between integers and floats, extend the exception-handling method:

def is_integer(s):
    try:
        s = s.strip()
        if not s:
            return False
        num = float(s)
        # Check if the float is an integer and the string lacks a decimal point
        return num.is_integer() and "." not in s
    except ValueError:
        return False

print(is_integer("123"))     # True
print(is_integer("123.0"))   # False (contains '.')
print(is_integer("123.5"))   # False

Final Recommendation

Use exception handling for simplicity and coverage of edge cases. If you need to exclude NaN or Inf, uncomment the relevant checks. For strict pattern control (e.g., disallow leading zeros), use the regex method.

Leave a Reply

Your email address will not be published. Required fields are marked *