Python isdigit(): What It Accepts and What It Rejects

isdigit() is a Python string method that returns True when every character in the string is a digit, and False otherwise.

"123".isdigit()     # True
"12a".isdigit()     # False
"-5".isdigit()      # False  <- catches people out
"3.14".isdigit()    # False  <- so does this

Those last two are why you’re probably here. A minus sign isn’t a digit and neither is a full stop, so isdigit rejects most real-world numbers.

Everything on this page ran on Python 3.12.5, and the screenshots are those runs.

What isdigit() does

It checks every character and returns a single boolean. One non-digit anywhere makes the whole thing False:

print("123".isdigit())        # True
print("abc".isdigit())        # False
print("12a".isdigit())        # False, every character must be a digit
print("".isdigit())           # False, an empty string has nothing to check

# it is a string method, so numbers have to be strings first
print(str(2026).isdigit())

Output:

True
False
False
False
True

An empty string returns False too, which is convenient: you don’t need a separate length check before calling it.

What isdigit() returns False for

This is the table worth remembering, because the surprises are all practical:

values = ["42", "-5", "3.14", "1_000", " 7 ", "٧", "²", "½", ""]

print(f"{'value':<8} {'isdigit':>8}")
for value in values:
    print(f"{value!r:<8} {value.isdigit()!s:>8}")

Output:

value     isdigit
'42'         True
'-5'        False
'3.14'      False
'1_000'     False
' 7 '       False
'٧'          True
'²'          True
'½'         False
''          False
Command Prompt showing Python isdigit returning False for a negative number, a decimal, an underscore separator and a padded string
Only '42' and the two Unicode digits pass.
  • "-5" — the minus sign is not a digit.
  • "3.14" — neither is the decimal point.
  • "1_000" — underscores are legal in Python literals, not in strings.
  • " 7 " — spaces count as characters, so strip first.

If you’re validating user input, strip the whitespace before the check and handle the sign yourself. That’s the same care any input check needs.

isdigit vs isdecimal vs isnumeric

Python has three of these and they disagree on exactly the characters you’d never think to test:

samples = ["42", "²", "½", "٧", "3.14", "-5"]

print(f"{'value':<8} {'isdigit':>8} {'isdecimal':>10} {'isnumeric':>10}")
for s in samples:
    print(f"{s!r:<8} {s.isdigit()!s:>8} {s.isdecimal()!s:>10} {s.isnumeric()!s:>10}")

print()
print("superscript two  -> isdigit True, isdecimal False")
print("one half         -> isnumeric True only")
print("arabic-indic 7   -> all three True")

Output:

value     isdigit  isdecimal  isnumeric
'42'         True       True       True
'²'          True      False       True
'½'         False      False       True
'٧'          True       True       True
'3.14'      False      False      False
'-5'        False      False      False

superscript two  -> isdigit True, isdecimal False
one half         -> isnumeric True only
arabic-indic 7   -> all three True
Command Prompt comparing isdigit, isdecimal and isnumeric on a superscript two, a one half fraction and an Arabic-Indic digit
Three methods, three different answers on the same characters.
MethodAcceptsExample that differs
isdecimal()Characters usable in a base-10 number"²".isdecimal() is False
isdigit()Decimals plus superscripts and subscripts"²".isdigit() is True
isnumeric()Everything above plus fractions and numerals"½".isnumeric() is True

isdecimal() is the strictest and usually the one you want, because it accepts exactly the characters int() can parse.

isnumeric() is the loosest. It says yes to "½" and to Roman numerals, neither of which int() will take.

Checking whether a string is really a number

Since isdigit refuses negatives and decimals, here are the two checks that actually work:

def is_whole_number(text):
    """True for '42' and '-5', False for '3.14' and 'abc'."""
    return text.lstrip("-").isdigit() and text not in ("", "-")


def is_any_number(text):
    """True for anything float() accepts, including decimals and negatives."""
    try:
        float(text)
        return True
    except ValueError:
        return False


for value in ["42", "-5", "3.14", "-3.14", "abc", "", "1e5"]:
    print(f"{value!r:<8} whole={is_whole_number(value)!s:<6} number={is_any_number(value)}")

Output:

'42'     whole=True   number=True
'-5'     whole=True   number=True
'3.14'   whole=False  number=True
'-3.14'  whole=False  number=True
'abc'    whole=False  number=False
''       whole=False  number=False
'1e5'    whole=False  number=True
Command Prompt showing a whole number check and a float based check agreeing and disagreeing on various strings
The float() version accepts decimals, negatives and scientific notation.

Stripping a leading minus before isdigit handles whole numbers including negatives. For anything else, try: float(text) is the honest test.

Note that the float() version accepts "1e5". If that’s not wanted, use the isdecimal check instead.

Validating input with isdigit

The most common real use is a prompt that keeps asking until it gets digits:

def read_age(prompt):
    while True:
        text = input(prompt).strip()
        if text.isdigit():                 # digits only: no minus, no decimal point
            return int(text)
        print("  please type a whole number")


age = read_age("Age: ")
print("you entered:", age)

Typing ‘twelve’, then ‘-3’, then a valid age:

Age:   please type a whole number
Age:   please type a whole number
Age: you entered: 34
Command Prompt showing a Python program rejecting the word twelve and a negative number before accepting a valid age
Both bad inputs rejected before the number is accepted.

isdigit suits this precisely because it’s strict. An age can’t be negative or fractional, so the method’s limitations become the validation rule. For measurements that can be decimal, use float() in a try block.

More Python string and input guides:

Frequently asked questions

What does isdigit() do in Python?

It returns True when every character in the string is a digit and the string is not empty. It is documented with the other string methods in the Python string reference.

Why does isdigit() return False for a negative number?

The minus sign is not a digit, so "-5".isdigit() is False. Strip the sign first, or use a float() check.

Why does isdigit() return False for 3.14?

The decimal point is not a digit either. Use try: float(text) when decimals are allowed.

What is the difference between isdigit and isnumeric?

isnumeric is looser: it accepts fractions such as "½" and other numerals that isdigit rejects.

What is the difference between isdigit and isdecimal?

isdecimal is stricter. Superscripts like "²" pass isdigit but fail isdecimal.

Does isdigit() work on an empty string?

It returns False, so you do not need a separate emptiness check before calling it.

Which should I use to validate a number from input()?

isdecimal() for whole numbers, or float() inside a try block when decimals and negatives are allowed.