bytes.maketrans()

A table builder, not a transformation. On its own it does nothing visible — its output exists purely to be handed to translate.

Bytes staticmethodPython 3.1+
Common call
bytes.maketrans(b'abc', b'xyz')
Returns
a 256-byte table — 738 characters of escapes if you print it
Replaces
building the identity table and patching it by hand
Watch out
both arguments must be the SAME length, or it raises
bytes.maketrans(fromfrom — Bytes to map from. Each byte here pairs positionally with one in to.type: bytes · required, toto — Bytes to map to. Must be exactly the same length as from.type: bytes · required)
→ bytes

Parameters

NameTypeRequiredDescription
frombytesyesBytes to map from. Each byte here pairs positionally with one in to.
tobytesyesBytes to map to. Must be exactly the same length as from.

Return value

bytes — A 256-byte table where position i holds the byte that i maps to. Bytes not mentioned map to themselves.

Examples

1. Build a table
bytes.maketrans(b'abc', b'xyz')
Returns
a 256-byte table
2. Use it
b'abcabc'.translate(bytes.maketrans(b'abc', b'xyz'))
Returns
b'xyzxyz'
3. Always 256 long
len(bytes.maketrans(b'a', b'x'))
Returns
256
4. Identity table
bytes.maketrans(b'', b'')
Returns
maps every byte to itself
5. Length mismatch
bytes.maketrans(b'ab', b'x')
Returns
ValueError: maketrans arguments must have same length
6. Unmapped pass through
b'abcdef'.translate(bytes.maketrans(b'ad', b'AD'))
Returns
b'AbcDef'

Pitfalls

1. The arguments must be the same length
Mapping is strictly positional and one byte to one byte, so a mismatch is meaningless and raises immediately. This is also why it cannot express deletions or expansions.
Mismatched
bytes.maketrans(b'ab', b'x')
ValueError: maketrans arguments must have same length
Pair them up
bytes.maketrans(b'ab', b'xy')
a valid table
2. It does not transform anything by itself
The name suggests action, but it only builds a lookup table. Calling it without passing the result to translate accomplishes nothing.
No effect
bytes.maketrans(b'a', b'x')
data
unchanged
Feed it to translate
data.translate(bytes.maketrans(b'a', b'x'))
transformed
3. Printing the table is useless
The result is a 256-byte object whose repr is hundreds of characters of escapes. It is data for the interpreter, not something to read or log.
Wall of escapes
print(bytes.maketrans(b'a', b'x'))
b'\x00\x01\x02... (738 chars)
Inspect one entry
bytes.maketrans(b'a', b'x')[ord('a')]
120 # ord("x")
4. Different from str.maketrans
The str version returns a DICT and accepts one, two or three arguments, including a form that deletes characters. The bytes version returns a 256-byte table and takes exactly two.
Wrong arity
bytes.maketrans(b'abc')
TypeError: maketrans() takes exactly 2 arguments
Two arguments
bytes.maketrans(b'abc', b'xyz')
a valid table

When to use

Use it
  • Preparing a table for bytes.translate
  • Fixed byte-level substitutions defined once and reused
  • Building a substitution cipher table
Reach for something else
  • One-off replacements → bytes.replace is simpler
  • Multi-byte sequences → maketrans cannot express them
  • Text rather than bytes → str.maketrans, which is a different shape

Notes

Complexity
O(256) — builds the identity table, then applies the pairs
Return
A new 256-byte bytes object, reusable across many translate calls
CPython impl
Objects/bytesobject.c :: bytes_maketrans
Memory
Exactly 256 bytes plus object overhead
Thread-safe
Yes — the table is immutable and safe to share

FAQ

One entry per possible byte value. Position i holds whatever byte i maps to, so translate is a single array lookup per byte — which is what makes it a one-pass operation regardless of how many mappings you defined.

bytes.maketrans(b'a', b'x')[97]
# 120

History

3.1
bytes.maketrans added as a staticmethod, replacing the Python 2 string.maketrans function.