str.translate()

Character-level transformation with a lookup table — build the table with str.maketrans, then apply in one linear pass.

String methodPython 1.6+Live demo
Common call
s.translate(str.maketrans("abc", "xyz"))
Returns
new str — the original is unchanged
Replaces
a chain of `.replace()` calls when every character is a single-character swap
Watch out
table keys are ORDINALS (integers), not characters — use str.maketrans to avoid the confusion
str.translate(tabletableA mapping from Unicode ordinal (integer) to Unicode ordinal, string, or None. Characters not in the table are passed through unchanged. Almost always built via str.maketrans().type: dict · required)
str

Demo

Live evaluation
Try:
Inputs
stringstrthe source
fromstrcharacters to replace
tostrreplacement chars, same length
Output
'hello'.translate('abc', 'xyz')
'hello'

The demo builds a table from your "from" and "to" strings (like str.maketrans("abc", "xyz")) — each character in "from" maps to the same-position character in "to". Characters not in "from" are passed through. Both strings must be the same length. Real code usually builds tables with str.maketrans, which also accepts a dict form and a "delete these chars" third argument.

Parameters

NameTypeRequiredDescription
tabledictyesA mapping from Unicode ordinal (integer) to Unicode ordinal, string, or None. Characters not in the table are passed through unchanged. Almost always built via str.maketrans().

Return value

strA copy of the string in which each character has been mapped through the given table. Keys are ORDINALS (integers, not characters); values may be integers, strings, or None (which deletes the character).

Common patterns

Batch character swap
One pass, no repeated string allocations.
table = str.maketrans("abc", "xyz")
result = text.translate(table)
Delete specific characters
Third argument to maketrans is the chars to delete.
clean = text.translate(str.maketrans("", "", "aeiou"))
# remove vowels
Strip accents
Combine translate with a Unicode normalization pass.
import unicodedata
def strip_accents(s):
    d = unicodedata.normalize("NFKD", s)
    return "".join(c for c in d if not unicodedata.combining(c))
Replace a character with multiple characters
Table values can be strings, not just single characters.
text.translate({ord("&"): "and"})

Examples

1. Basic swap
"hello".translate(str.maketrans("l", "L"))
Returns
"heLLo"
2. Multi-char swap
"abc".translate(str.maketrans("abc", "xyz"))
Returns
"xyz"
3. Delete chars
"hello".translate(str.maketrans("", "", "l"))
Returns
"heo"
4. Table with strings
"a&b".translate({ord("&"): "and"})
Returns
"aandb"
5. None deletes
"hello".translate({ord("l"): None})
Returns
"heo"
6. No matches
"hello".translate(str.maketrans("xyz", "abc"))
Returns
"hello"

Pitfalls

1. Table keys are ORDINALS, not characters
The most common translate confusion. A dict with string keys does not work — you need integer ordinals. str.maketrans handles this for you.
String keys silent no-op
"hello".translate({"l": "L"})
"hello" # nothing matched
Use maketrans
"hello".translate(str.maketrans("l", "L"))
"heLLo"
2. None deletes; empty string does not exist
A value of None removes the character from the output. The empty string as a value would leave an empty string (which happens to look the same). Some people expect "" to be the "delete" sentinel — it is not; None is.
Empty string keeps position
"abc".translate({ord("b"): ""})
"ac" # actually works — empty string joins fine
None is canonical
"abc".translate({ord("b"): None})
"ac"
3. maketrans two-string form: lengths MUST match
When called with two strings, str.maketrans requires them to be the same length. Different lengths raise ValueError.
Length mismatch
str.maketrans("abc", "xy")
ValueError: the first two maketrans arguments must have equal length
Same length
str.maketrans("abc", "xyz")
valid table
4. translate is a pure operation — the original is unchanged
Like all string methods, translate returns a new string. Assigning it back is required.
Lost result
s = "hello"
s.translate(str.maketrans("l", "L"))
print(s)
"hello" # unchanged
Capture it
s = s.translate(str.maketrans("l", "L"))
"heLLo"

When to use

Use it
  • Batch single-character substitutions in one linear pass
  • Character deletion via the maketrans third argument
  • Building a stripping / escaping / obfuscation table once and applying many times
  • Any transformation that would otherwise chain many .replace() calls
Reach for something else
  • Multi-character substrings → str.replace or re.sub
  • Case-insensitive replacement → normalize with casefold, then translate
  • Regex-based transforms → re.sub with a callable
  • Accent stripping via character mapping alone — combine with unicodedata

Notes

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

FAQ

For efficiency — internally CPython indexes the table by codepoint. Using integers keeps the lookup a plain integer indexing operation. In practice you never touch the ordinals directly; str.maketrans converts strings for you.

History

1.6
translate() introduced along with the string-table concept.
3.0
Table keys became ordinals (integers); the older bytes-based translate remains for bytes objects.