str.swapcase()

Toggle case per character — a display gimmick more than a comparison tool. Uses Unicode case mappings.

String methodPython 1.0+Live demo
Common call
text.swapcase()
Returns
new str — the original is unchanged
Replaces
a manual `"".join(c.lower() if c.isupper() else c.upper() for c in s)`
Watch out
NOT round-trippable for some Unicode characters; use for display, not for parity checks
str.swapcase()
str

Demo

Live evaluation
Try:
Inputs
stringstrthe source
Output
'Hello World'.swapcase()
'hELLO wORLD'

swapcase toggles the case of every letter — uppercase becomes lowercase, lowercase becomes uppercase. Non-letters (digits, punctuation, whitespace) pass through unchanged. It uses Unicode case mappings, so accented characters swap too. It is not guaranteed that s.swapcase().swapcase() equals s — some Unicode characters do not round-trip. Use swapcase for display effects, not for parity checks.

Common patterns

Fix typed-with-Caps-Lock text
The classic use case — someone typed with Caps Lock on and Shift for capitals.
fixed = accidentally_capsed.swapcase()
Alternating-case demo effect
Swap case per position in a loop — a stylistic touch.
stylized = "".join(c.swapcase() if i % 2 else c
                    for i, c in enumerate(text))
Diagnostic reversal for tests
Quick way to see whether a case-insensitive comparator is really case-insensitive.
assert compare_case_insensitive(s, s.swapcase())

Examples

1. Mixed case
"Hello World".swapcase()
Returns
"hELLO wORLD"
2. All upper
"HELLO".swapcase()
Returns
"hello"
3. All lower
"hello".swapcase()
Returns
"HELLO"
4. Digits unchanged
"Abc123".swapcase()
Returns
"aBC123"
5. Punctuation unchanged
"Don\'t Stop!".swapcase()
Returns
"dON\'T sTOP!"
6. Unicode accents
"Café".swapcase()
Returns
"cAFÉ"
7. Empty is empty
"".swapcase()
Returns
""

Pitfalls

1. NOT round-trippable for some Unicode characters
The Python docs say "It is not necessarily true that s.swapcase().swapcase() == s". Special-case characters like German ß (lowercase) map to SS (uppercase), and SS swapcased maps to ss — you lost the ß.
ß round-trip fails
"Straße".swapcase().swapcase()
"strasse" # not "Straße"
Do not rely on parity
# swapcase is for display effects — do NOT use it for identity round-trips
2. Not the same as .lower() then .upper()
swapcase flips per character. Chaining lower and upper collapses everything to one case. Different intent, different result.
Chain destroys mix
"Hello".lower().upper()
"HELLO"
swapcase preserves mix
"Hello".swapcase()
"hELLO"
3. Not case-insensitive comparison
swapcase produces a different string, not a normalized one. Two strings that mean the same thing case-insensitively can swap to different results. Use casefold for comparison.
Wrong tool
"Hi".swapcase() == "hi".swapcase()
False # "hI" != "HI"
Use casefold
"Hi".casefold() == "hi".casefold()
True
4. Original string is NOT modified
Like all string methods, swapcase returns a new string. Assigning it back is required for the swapped value to persist.
Lost result
s = "Hello"
s.swapcase()
print(s)
"Hello" # unchanged
Capture it
s = s.swapcase()
print(s)
"hELLO"

When to use

Use it
  • Fixing text typed with Caps Lock stuck on
  • Stylistic case flips for display or logging
  • Demo / educational output showing case behavior
  • Diagnostic reversals in tests of case-insensitive comparators
Reach for something else
  • Case-insensitive equality comparison → str.casefold
  • Normalizing to a specific case → str.lower or str.upper
  • Round-tripping through swapcase — not guaranteed to be identity-safe
  • Display formatting — usually lower / upper / title read more clearly

Notes

Complexity
O(n)
Return
A new string; the original is unchanged (strings are immutable)
CPython impl
Objects/unicodeobject.c :: unicode_swapcase
Memory
Allocates one new string
Thread-safe
Yes — strings are immutable

FAQ

No. For most ASCII text it does, but some Unicode characters — like German ß — map to a multi-character uppercase (SS), so the reverse loses the original character. The docs explicitly say `s.swapcase().swapcase()` is not guaranteed to equal `s`.

History

1.0
swapcase() has been part of str since Python 1.0.
3.0
Full Unicode support — case mappings applied per the Unicode standard.