string.capwords
One line of Python: (sep or ' ').join(map(str.capitalize, s.split(sep))). That explains everything it does — including lowercasing the rest of each word and squeezing whitespace.
Demo
import string (string.capwords("they're bill's friends"), "they're bill's friends".title())
title() treats every non-letter as a word boundary, so it gives "They'Re" and "1St"; capwords only splits on whitespace. Both lowercase the rest of each word. With sep=' ' the empty strings between doubled spaces are kept, so the spacing survives; with sep=None it collapses. In 'ΟΔΟΣ' the final capital sigma lowercases to ς, as in str.lower().
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| s | str | yes | The text. |
| sep | str | None | no (None) | None: split on runs of any whitespace, drop leading/trailing whitespace, join with ' '. A string: split on exactly that separator and join with it again. '' raises ValueError. |
Return value
str — The capitalized words joined by sep (by a single space when sep is None).
Common patterns
import string display = string.capwords(raw_name.strip())
import string name = "-".join(string.capwords(part) for part in raw.split("-"))
fixed = " ".join(w[:1].upper() + w[1:] for w in text.split())
Examples
Pitfalls
import string string.capwords('NASA and iPhone')
' '.join(w[:1].upper() + w[1:] for w in 'NASA and iPhone'.split())
import string string.capwords('jean-luc picard', '-')
import string ' '.join(string.capwords(w, '-') for w in 'jean-luc picard'.split())
When to use
- Title-casing names, headings and labels where title() would produce "Don'T"
- Cleaning up messy spacing and capitalization in one call
- Text with acronyms or brand names that must keep their capitals
- Real headline style (small words lowercase) → write your own rule
Notes
FAQ
string.capwords(s) — or s.title() if the text has no apostrophes or digits. capwords("don't stop") gives "Don't Stop"; "don't stop".title() gives "Don'T Stop".