string.ascii_letters / digits / punctuation …
Plain strings you test membership against or build alphabets from. All nine are ASCII only and never depend on the locale — and because they are strings, "in" is a substring test, not a character test.
Demo
import string names = ['ascii_lowercase', 'ascii_uppercase', 'digits', 'hexdigits', 'octdigits', 'punctuation', 'whitespace'] [n for n in names if 'a' in getattr(string, n)]
'7' is in digits, hexdigits and octdigits at once. 'ab' is found in ascii_lowercase because in tests for a substring, and the empty string is a substring of everything — so test characters one at a time, as the validate tab does. all() of nothing is True, so an empty string passes validation unless you check its length too. string.letters existed only in Python 2.
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| ascii_lowercase | str | 'abcdefghijklmnopqrstuvwxyz' (26) |
| ascii_uppercase | str | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' (26) |
| ascii_letters | str | ascii_lowercase + ascii_uppercase (52), lowercase first |
| digits | str | '0123456789' |
| hexdigits | str | '0123456789abcdefABCDEF' (22) |
| octdigits | str | '01234567' |
| punctuation | str | The 32 ASCII punctuation and symbol characters !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ |
| whitespace | str | ' \t\n\r\x0b\x0c' — space, tab, newline, carriage return, vertical tab, form feed |
| printable | str | digits + ascii_letters + punctuation + whitespace (100 characters) |
Common patterns
import string table = str.maketrans("", "", string.punctuation) clean = text.translate(table)
import secrets, string alphabet = string.ascii_letters + string.digits token = "".join(secrets.choice(alphabet) for _ in range(20))
import string allowed = set(string.ascii_lowercase + string.digits + "-") ok = slug != "" and set(slug) <= allowed
import string pos = string.ascii_lowercase.index(letter.lower()) + 1
Examples
Pitfalls
import string '' in string.digits, '123' in string.digits
import string s = '' bool(s) and all(c in string.digits for c in s)
import string 'é' in string.ascii_letters, '٣' in string.digits
'é'.isalpha(), '٣'.isdigit()
import string '\n' in string.printable, '\n'.isprintable()
import string set(string.printable) - set(string.whitespace) == {c for c in map(chr, range(128)) if c.isprintable() and c != ' '}
When to use
- Building alphabets for tokens, IDs and puzzles
- Filtering or validating ASCII-only input (identifiers, hex codes, slugs)
- Natural-language text → str.isalpha(), isdigit(), isspace() (Unicode-aware)
- Complex validation → re with a character class, e.g. re.fullmatch(r"[0-9a-f]+", s)
Notes
FAQ
import string, then string.ascii_lowercase is 'abcdefghijklmnopqrstuvwxyz'; list(string.ascii_lowercase) gives the list. ascii_uppercase has A-Z and ascii_letters both (lowercase first).