When working with user input or parsing data, checking if a string contains only numbers is a common task in Python. Two built-in methods often come up for this: str.isdigit()
and str.isnumeric()
. At first glance, they seem interchangeable, but subtle differences can lead to unexpected behavior if you don’t pick the right one.
In this article, we'll dive deep into both methods, compare their behavior—especially with Unicode characters—cover practical examples, and share tips for when each one shines. By the end, you'll know exactly which method to call when you need to validate numeric input.
Understanding isdigit()
The str.isdigit()
method returns True
if all characters in the string are digits and there is at least one character. Digits here refer to characters in the Unicode category “Nd” (Number, decimal digit).
print("12345".isdigit()) # True
print("١٢٣٤٥".isdigit()) # True (Arabic–Indic digits)
print("²³".isdigit()) # True (superscript digits)
print("12.3".isdigit()) # False (period is not a digit)
Key points:
- Only characters with Unicode property Nd count.
- No signs (
+
/-
) or decimal points. - Works well for basic decimal digits across scripts.
Tip: If you need to process each character, consider splitting a Python string into characters first.
Understanding isnumeric()
str.isnumeric()
is broader. It returns True
for any string where all characters are numeric characters, including:
- Decimal digits (Nd)
- Vulgar fractions (e.g., ¼, ½)
- Roman numerals (ↀ, ↂ)
- Other numeric characters (², Ⅻ)
print("12345".isnumeric()) # True
print("①②③".isnumeric()) # True (circled numbers)
print("⅓⅔".isnumeric()) # True (fractions)
print("五".isnumeric()) # False (Chinese numeral, no numeric property)
Points to note:
- More permissive than
isdigit()
. - Catches Unicode numbers beyond standard digits.
- Will still reject letters, punctuation, spaces.
When to Use Each
Choosing between isdigit()
and isnumeric()
depends on the input you expect:
- Use
isdigit()
when you only want standard decimal digits, possibly in various scripts. Great for parsing IDs or zip codes. - Use
isnumeric()
when you want to accept numeric forms like fractions or superscripts. Useful in math processing or display parsing.
Bullet summary:
-
Strict integer check: use
isdigit()
. -
Broader numeric check: use
isnumeric()
.
Edge Cases with Unicode
Unicode adds complexity:
print("²".isdigit(), "²".isnumeric()) # True True
print("Ⅵ".isdigit(), "Ⅵ".isnumeric()) # False True (Roman numeral VI)
print("๐".isdigit(), "๐".isnumeric()) # True True (Thai digit zero)
■ Roman numerals are numeric but not digits.
■ Some scripts have their own digits (Thai, Arabic–Indic).
Pro Tip: Always test your expected range of characters, especially with international text.
Performance Considerations
Both methods are implemented in C, so they're fast. But when processing large datasets:
import timeit
stmt1 = '"1234567890".isdigit()'
stmt2 = '"Ⅻ".isnumeric()'
print(timeit.timeit(stmt1, number=1000000))
print(timeit.timeit(stmt2, number=1000000))
You may see marginal differences. If profiling shows a hotspot, filter with a regex or custom logic.
Practical Validation Example
Imagine a form where users enter an age or a fraction:
def validate_input(s):
if s.isdigit():
return int(s)
if s.isnumeric():
# Convert fractions or superscripts
return float(s) if '.' in s else None
raise ValueError("Not a valid number")
print(validate_input("27")) # 27
print(validate_input("½")) # None or custom handling
By picking the right method, you avoid rejecting valid input or accepting invalid data.
Conclusion
str.isdigit()
and str.isnumeric()
look similar but serve different needs. Use isdigit()
for a strict check of decimal digits, and isnumeric()
when you need to catch a wider range of Unicode numerals—fractions, superscripts, or other numeric symbols. Always test edge cases against your data set, and consider performance if you loop over millions of strings. With these tools in your belt, you can validate numeric input in Python cleanly and confidently.
Ready to write bullet-proof validation? Choose your method, test your data, and ship bug-free code!
Top comments (0)