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.

string constantsPython 3 (all)Live demo
Common call
c in string.punctuation
Returns
bool — or the str itself, e.g. string.digits is '0123456789'
Replaces
hand-typed 'abcdefghijklmnopqrstuvwxyz' and chr(ord('a') + i) loops
Watch out
'' and multi-character strings: '' in string.digits is True
string.ascii_letters · ascii_lowercase · ascii_uppercase · digits · hexdigits · octdigits · punctuation · printable · whitespace
→ str

Demo

Live evaluation
Which constants contain the text? Try one character, then two, then an empty string.
Try:
Inputs
chstra character
Code
import string
names = ['ascii_lowercase', 'ascii_uppercase', 'digits', 'hexdigits', 'octdigits', 'punctuation', 'whitespace']
[n for n in names if 'a' in getattr(string, n)]
Result
['ascii_lowercase', 'hexdigits']

'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

AttributeTypeMeaning
ascii_lowercasestr'abcdefghijklmnopqrstuvwxyz' (26)
ascii_uppercasestr'ABCDEFGHIJKLMNOPQRSTUVWXYZ' (26)
ascii_lettersstrascii_lowercase + ascii_uppercase (52), lowercase first
digitsstr'0123456789'
hexdigitsstr'0123456789abcdefABCDEF' (22)
octdigitsstr'01234567'
punctuationstrThe 32 ASCII punctuation and symbol characters !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
whitespacestr' \t\n\r\x0b\x0c' — space, tab, newline, carriage return, vertical tab, form feed
printablestrdigits + ascii_letters + punctuation + whitespace (100 characters)

Common patterns

Remove punctuation
A translate table deletes every listed character in one pass.
import string
table = str.maketrans("", "", string.punctuation)
clean = text.translate(table)
Random token
secrets.choice over a constant alphabet — never random for security.
import secrets, string
alphabet = string.ascii_letters + string.digits
token = "".join(secrets.choice(alphabet) for _ in range(20))
Fast membership with a set
Turn a constant into a set when testing many characters.
import string
allowed = set(string.ascii_lowercase + string.digits + "-")
ok = slug != "" and set(slug) <= allowed
Letter positions
index() on ascii_lowercase gives 0-based alphabet positions.
import string
pos = string.ascii_lowercase.index(letter.lower()) + 1

Examples

1. ascii_letters: lowercase first
import string string.ascii_letters
Returns
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
2. hexdigits has both cases
import string string.hexdigits
Returns
'0123456789abcdefABCDEF'
3. punctuation
import string string.punctuation
Returns
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
4. whitespace
import string string.whitespace
Returns
' \t\n\r\x0b\x0c'
5. Sizes
import string len(string.punctuation), len(string.printable)
Returns
(32, 100)
6. Alphabet positions
import string [string.ascii_lowercase.index(c) + 1 for c in 'abz']
Returns
[1, 2, 26]
7. ASCII only
import string 'é' in string.ascii_letters, '\xa0' in string.whitespace
Returns
(False, False)

Pitfalls

1. "in" tests substrings, not characters
A multi-character or empty string passes the test as long as it appears somewhere in the constant.
text in digits
import string
'' in string.digits, '123' in string.digits
(True, True)
every character
import string
s = ''
bool(s) and all(c in string.digits for c in s)
False
2. Expecting Unicode letters, digits and spaces
The constants are ASCII. Accented letters, Arabic-Indic digits and the no-break space are missing; the str methods know them.
constants
import string
'é' in string.ascii_letters, '٣' in string.digits
(False, False)
str methods
'é'.isalpha(), '٣'.isdigit()
(True, True)
3. printable is not str.isprintable()
string.printable includes tab, newline and the other whitespace controls; str.isprintable() rejects them (only the space counts).
assume equal
import string
'\n' in string.printable, '\n'.isprintable()
(True, False)
pick the one you mean
import string
set(string.printable) - set(string.whitespace) == {c for c in map(chr, range(128)) if c.isprintable() and c != ' '}
True

When to use

Use it
  • Building alphabets for tokens, IDs and puzzles
  • Filtering or validating ASCII-only input (identifiers, hex codes, slugs)
Reach for something else
  • 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

CPython impl
Lib/string.py defines them as literals: whitespace = ' \t\n\r\v\f', ascii_letters = ascii_lowercase + ascii_uppercase, printable = digits + ascii_letters + punctuation + whitespace
Mutability
They are module attributes: rebinding string.digits is possible but affects every user of the module — never do it
Python 2
letters, lowercase, uppercase (locale-dependent), maketrans and the function versions of str methods were removed in Python 3

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).