str.isalnum()

The letters-OR-digits check — the union of isalpha and (isdigit / isnumeric / isdecimal).

String methodPython 1.0+Live demo
Common call
if token.isalnum():
Returns
True or False
Replaces
a manual loop of `if not (ch.isalpha() or ch.isdigit()): return False`
Watch out
empty string → False; underscores and spaces both break it
str.isalnum()
bool

Demo

Live evaluation
Try:
Inputs
stringstrthe string to test
Output
'hello'.isalnum()
True

isalnum() returns True when EVERY character is either a letter or a digit AND the string is non-empty. Spaces, underscores, hyphens, dots, and any other punctuation all break it. "Letter" and "digit" are Unicode-aware — accented letters and non-Latin scripts pass, but so do numeric characters from other systems. The empty string returns False by convention.

Common patterns

Loose identifier check
Real identifiers also allow underscores; for a proper check use str.isidentifier().
if not token.isalnum():
    raise ValueError("letters and digits only")
Reject punctuation and whitespace
A quick sanity check on user-typed short codes.
if not code.isalnum():
    return False
Combine with isdigit for "has at least one letter"
A common validation shape.
if token.isalnum() and not token.isdigit():
    ...    # has letters, may have digits

Examples

1. Letters only
"hello".isalnum()
Returns
True
2. Digits only
"12345".isalnum()
Returns
True
3. Mixed
"hello123".isalnum()
Returns
True
4. Space breaks it
"hello world".isalnum()
Returns
False
5. Unicode passes
"café1".isalnum()
Returns
True
6. Underscore fails
"user_name".isalnum()
Returns
False
7. Empty is False
"".isalnum()
Returns
False
8. Punctuation fails
"a.b".isalnum()
Returns
False

Pitfalls

1. Empty string returns False, not True
Same rule as isalpha and isdigit — the empty case is False by convention. isalnum requires at least one character.
Wrong expectation
"".isalnum()
False
Read the contract
"".isalnum()   # always False
"".isdigit()   # always False
"".isspace()   # always False
documented behaviour
2. Underscores are NOT alphanumeric
Underscore is punctuation, not a letter or digit. Passwords, IDs, and identifiers that contain underscores fail isalnum. For proper identifier checking, use str.isidentifier().
Fails on _
"user_id".isalnum()
False
Identifier check
"user_id".isidentifier()
True
3. Spaces are NOT alphanumeric
A single space breaks isalnum. Split first if multi-token input is legitimate.
Multi-token fails
"hello world 123".isalnum()
False # spaces
Per token
all(t.isalnum() for t in text.split())
True
4. Unicode "digits" include surprising code points
Roman numerals, superscripts, and fractions pass isnumeric AND isalnum — a quirk if you expected ASCII digits only. Combine with .isascii() when that matters.
Too permissive
"Ⅳ".isalnum()
True # Roman numeral
ASCII only
name.isascii() and name.isalnum()
True only for ASCII letters/digits

When to use

Use it
  • Quick validation that a token has no punctuation or whitespace
  • Loose "letters or digits, that's it" check on short codes
  • Combined with .split() for word-by-word validation
  • Composing with isalpha / isdigit / isspace for finer checks
Reach for something else
  • Proper identifier check — use str.isidentifier() (allows underscores, forbids leading digits)
  • ASCII-only validation → combine with .isascii()
  • Rich validation (length, format) → use a regex or validator library
  • Values that legitimately contain spaces → split first

Notes

Complexity
O(n) — one linear scan
Return
bool — True or False
CPython impl
Objects/unicodeobject.c :: unicode_isalnum
Memory
No allocation
Thread-safe
Yes — strings are immutable

FAQ

Underscore is punctuation, not a letter or digit. For identifier-shaped strings (which include underscores), use str.isidentifier() instead.

History

1.0
isalnum() has been part of str since Python 1.0.
3.0
Full Unicode support — accepts letters and digits from any script per Unicode categorization.