Python Bytes and Bytearray
Learn how Python represents binary data with immutable bytes and mutable bytearray objects, including indexing, slicing, construction, encoding boundaries, and common binary operations.
Basic
Python has two core built-in types for working with binary data:
bytes and
bytearray. Both are sequences of values from 0 through 255. The important difference is simple:
bytes is immutable, while
bytearray is mutable.
Bytes are immutable binary sequences
A
bytes object is an immutable sequence. A bytes literal uses a
b prefix, and each indexed item is an integer representing one byte.
data = b"Foxipa"
print(data)
print(data[0])
print(data[-1])
print(len(data))Indexing
bytes gives an integer, not a one-character string. Slicing still gives a
bytes object.
data = b"Python"
print(data[0])
print(data[1:4])
print(type(data[1:4]).__name__)Create bytes from numeric values or hexadecimal text
Use
bytes with an iterable of integers when you already have numeric byte values.
bytes.fromhex() is useful when binary data is written as pairs of hexadecimal digits in text.
packet = bytes([80, 89, 84, 72, 79, 78])
hex_packet = bytes.fromhex("50 59 54 48 4f 4e")
print(packet)
print(hex_packet)
print(packet == hex_packet)Every integer supplied this way must be in the range 0 through 255. A value outside that range raises
ValueError.
Bytearray changes in place
A
bytearray is the mutable counterpart to
bytes. It uses the same byte-value range, but you can change individual items or slices after creation.
buffer = bytearray(b"cat")
buffer[0] = ord("b")
buffer[1:3] = b"ee"
buffer.extend(b"!")
print(buffer)
print(bytes(buffer))As with
bytes, indexing a
bytearray returns an integer. A slice is another
bytearray object. Because it is mutable, a
bytearray is not hashable and cannot be used as a dictionary key or set element.
Bytes are not strings
A
str represents text. A
bytes object represents bytes. Moving between them requires an explicit text encoding or decoding operation; Python does not silently treat arbitrary bytes as text.
text = "Café"
data = text.encode("utf-8")
restored = data.decode("utf-8")
print(data)
print(restored)
print(type(data).__name__)
str.encode() converts text to
bytes using an encoding, while
bytes.decode() converts bytes back to text using an encoding. The same boundary appears in text file I/O, where the text stream handles encoding and decoding for you.
Common byte operations
bytes and
bytearray support the common sequence operations you already know: indexing, slicing, iteration, length, membership, concatenation, and repetition. They also provide binary-focused operations such as
hex() and
fromhex(). Use these types when the data itself is bytes, not when you simply need ordinary text.
data = b"ABCABC"
print(data.hex())
print(b"BC" in data)
print(data.find(b"CA"))
print(data + b"!")Choose the mutable or immutable form deliberately
Choose
bytes when the binary value should not be changed. Choose
bytearray when you need to update the bytes in place. Converting a
bytearray to
bytes creates an immutable bytes object from its current contents.
original = bytearray(b"ready")
original[0] = ord("R")
final = bytes(original)
print(original)
print(final)
print(type(final).__name__)Keep binary data and text separate
The main mental model is:
str is text, while
bytes and
bytearray are binary sequences. Encode at the text-to-bytes boundary and decode at the bytes-to-text boundary. Do not add or remove characters from binary data by treating it as if it were a string.
When you are ready, take the Python Bytes and Bytearray quiz — then complete the coding exercise.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.