23. Bytes & Bytearrays

In Python, bytes and bytearrays are binary data types used to store sequences of raw 8-bit integers (values from 0 to 255).
While text strings (str) store human-readable characters using Unicode, bytes store raw machine-readable binary data such as images, audio files, network packets, or file streams.
Python provides two primary types: bytes (immutable / unchangeable) and bytearray (mutable / changeable).
# Creating a bytes object using the b prefix
raw_data = b"Hello"

print(type(raw_data))  # Output: <class 'bytes'>
print(raw_data[0])     # Output: 72 (ASCII integer value for 'H')

23.1. The Bytes Data Type (bytes)

The bytes data type represents an immutable sequence of integers in the range 0 <= x < 256:

  • Literals with b Prefix: Defined by prefixing quotes with b, such as b"text" (ASCII characters only).

  • Integer Sequence: Accessing an index returns the integer ASCII code, not a string character.

  • Immutability: Once created, individual elements of a bytes object cannot be modified or reassigned.

  • Creation via bytes(): Can be created using the bytes() constructor with a list of integers or a specified size.

data = b"ABC"

# Reading elements returns integer ASCII values
print(data[0])  # Output: 65 (ASCII for 'A')
print(data[1])  # Output: 66 (ASCII for 'B')

# Creating bytes from a list of integers
numbers = bytes([72, 101, 108, 108, 111])
print(numbers)  # Output: b'Hello'

23.1.1. Quiz: The Bytes Data Type

23.1.1.1. Fill-in-the-Blanks (Cloze)

Complete the following sentences by filling in the blanks.
Word Bank (Drag items below):
255
65
b
bytes
immutable

1. To define a bytes literal in Python, place the prefix Drop here before the quote marks.
2. Bytes objects store sequences of integers ranging from 0 to Drop here.
3. The `bytes` data type is Drop here, meaning its contents cannot be altered after creation.
4. Accessing `b"A"[0]` returns the ASCII integer value Drop here.
5. Raw binary data like images and network packets are stored using Drop here in Python.

23.1.1.2. Code Ordering Examples

Example 1: Define a bytes literal and print its type and first byte integer value.

Drag and drop lines into the correct order and click to adjust indentation:
☰
print(type(sample_bytes))
☰
print(sample_bytes[0])
☰
sample_bytes = b"Python"

Example 2: Construct a bytes object from a list of ASCII integer codes.

Drag and drop lines into the correct order and click to adjust indentation:
☰
byte_data = bytes(code_list)
☰
print(byte_data)
☰
code_list = [80, 121, 116, 104, 111, 110]

Example 3: Initialize a zero-filled bytes object of a given length.

Drag and drop lines into the correct order and click to adjust indentation:
☰
buffer_size = 5
☰
print(empty_buffer)
☰
empty_buffer = bytes(buffer_size)

23.1.1.3. Multiple Choice Questions

Progress: 0
Score: 0 / 0
Question 1 of 0

How do you write a bytes literal in Python?

Correct! Adding the prefix ‘b’ before quotation marks creates a bytes literal.

Incorrect. The prefix ‘b’ must go before the opening quote.

Incorrect. While a constructor, literal syntax specifically uses the b prefix.

Incorrect. That is BBCode formatting, not Python syntax.

What range of integer values can an individual byte represent in Python?

Correct! An 8-bit byte represents 256 distinct integer values from 0 through 255.

Incorrect. Bytes use 8 bits, allowing up to 255.

Incorrect. Python bytes store unsigned integers from 0 to 255.

Incorrect. Byte indexing is zero-based starting at 0 up to 255.

Given data = b"Code", what is returned by data[0]?

Correct! Indexing returns the integer ASCII code for ‘C’, which is 67.

Incorrect. Indexing a bytes object returns an integer, not a string character.

Incorrect. Indexing returns a single integer value, not a bytes slice.

Incorrect. Index 0 returns the byte value at that position.

What happens if you try to reassign an element in a bytes object (e.g., b[0] = 65)?

Correct! Bytes objects cannot be modified after creation.

Incorrect. Bytes are immutable.

Incorrect. Object type does not change automatically.

Incorrect. An exception is raised.

What is the output of bytes(4)?

Correct! Passing an integer to bytes() creates a sequence of zero-bytes of that length.

Incorrect. Passing an integer specifies buffer size, not character content.

Incorrect. Result is a bytes object, not a list.

Incorrect. Passing an integer length is valid.

Which function checks the number of bytes stored in a bytes object?

Correct! The len() function returns the total count of bytes.

Incorrect. Python uses len() for sequence lengths.

Incorrect. count() searches for specific occurrences inside sequences.

Incorrect. No bytecount() function exists in standard Python.

What does bytes([65, 66, 67]) evaluate to?

Correct! Integers 65, 66, and 67 correspond to ASCII characters ‘A’, ‘B’, and ‘C’.

Incorrect. Converts the list of integers into a bytes object.

Incorrect. Integers are mapped to ASCII character equivalents.

Incorrect. Passing a list of integers in range 0-255 is valid.

Why are bytes preferred over str for handling binary image files?

Correct! Bytes store exact binary byte representations required for media files.

Incorrect. Primary reason is accurate binary representation.

Incorrect. Strings have no such arbitrary small limit.

Incorrect. Bytes store uncompressed raw data.

What type of error occurs if you pass an integer outside 0-255 to bytes([300])?

Correct! Byte values must strictly remain within the 0 to 255 integer range.

Incorrect. A ValueError is raised due to out-of-range value.

Incorrect. KeyErrors are related to dictionary lookups.

Incorrect. Python raises ValueError for byte integer range violations.

What is returned by type(b"123")?

Correct! The b prefix creates an instance of the bytes class.

Incorrect. The b prefix makes it a bytes object, not a string.

Incorrect. It is a sequence of bytes, not an integer.

Incorrect. Literal b syntax produces immutable bytes.

Question 1 of 0

23.2. The Bytearray Data Type (bytearray)

The bytearray data type is the mutable (changeable) version of bytes:

  • Mutability: Elements within a bytearray can be updated, appended, or removed in place.

  • In-place Modification: Support item assignment like data[0] = 90 or list-like methods such as .append().

  • Conversion: Easily created from strings (with encoding), existing bytes, or lists of integers.

  • Performance: Ideal for building or modifying binary buffers dynamically in memory.

# Creating a bytearray from a bytes object
mutable_bytes = bytearray(b"Hello")

# Modifying the first byte ('H' -> 'J')
mutable_bytes[0] = 74
print(mutable_bytes)  # Output: bytearray(b'Jello')

# Appending a new byte value (ASCII '!')
mutable_bytes.append(33)
print(mutable_bytes)  # Output: bytearray(b'Jello!')

23.2.1. Quiz: The Bytearray Data Type

23.2.1.1. Fill-in-the-Blanks (Cloze)

Complete the following sentences by filling in the blanks.
Word Bank (Drag items below):
.append()
255
buffer
bytes()
mutable

1. Unlike `bytes`, the `bytearray` type is Drop here and can be changed in place.
2. To add a new byte to the end of a `bytearray`, use the Drop here method.
3. Updating an element in a bytearray requires providing an integer between 0 and Drop here.
4. You can convert a `bytearray` back into immutable `bytes` using the Drop here function.
5. A `bytearray` is commonly used as a dynamic memory Drop here when receiving network data.

23.2.1.2. Code Ordering Examples

Example 1: Convert a bytes object to a bytearray and modify its first element.

Drag and drop lines into the correct order and click to adjust indentation:
☰
buffer = bytearray(original)
☰
print(buffer)
☰
buffer[0] = 98
☰
original = b"cat"

Example 2: Construct an empty bytearray and append byte values.

Drag and drop lines into the correct order and click to adjust indentation:
☰
data_stream = bytearray()
☰
data_stream.append(105)
☰
print(data_stream)
☰
data_stream.append(72)

Example 3: Modify a bytearray and convert it back to immutable bytes.

Drag and drop lines into the correct order and click to adjust indentation:
☰
print(final_bytes)
☰
final_bytes = bytes(packet)
☰
packet[0] = 80
☰
packet = bytearray(b"Ping")

23.2.1.3. Multiple Choice Questions

Progress: 0
Score: 0 / 0
Question 1 of 0

What primary advantage does bytearray offer over bytes?

Correct! Bytearrays allow in-place modification of elements.

Incorrect. Individual elements are still constrained to 0-255.

Incorrect. Translation is not a native bytearray feature.

Incorrect. Mutability is its key functional distinction.

Given ba = bytearray(b"hi"), what does ba.append(33) do?

Correct! .append() adds an integer byte to the end.

Incorrect. Appending valid integer byte values is fully supported.

Incorrect. .append() attaches to the end, not overwrite index 0.

Incorrect. Appends a new byte element.

What is output by ba = bytearray([65, 66]); ba[0] = 90; print(ba)?

Correct! Value 90 corresponds to ASCII ‘Z’, replacing 65 (‘A’).

Incorrect. Index 0 was updated to 90 (‘Z’).

Incorrect. Index 0 (‘A’) was changed, leaving index 1 (‘B’) unchanged.

Incorrect. Item assignment is allowed on bytearrays.

Which method converts a bytearray instance into an immutable bytes object?

Correct! Passing a bytearray to the bytes() constructor creates an immutable copy.

Incorrect. to_bytes() is an integer method.

Incorrect. str() generates string representation rather than bytes object.

Incorrect. No .freeze() method exists.

What happens if you execute ba = bytearray(b"test"); ba[0] = "T"?

Correct! Bytearray elements must be integers (0-255), not string characters.

Incorrect. Assigning string literals raises TypeError.

Incorrect. Must pass integer ASCII value (84 for ‘T’).

Incorrect. TypeError halts execution before modifications occur.

How do you assign the letter ‘A’ to index 0 of ba = bytearray(b"hello") correctly?

Correct! 65 is the integer ASCII value for capital ‘A’.

Incorrect. Bytearrays require integer values, not string characters.

Incorrect. Assigning bytes slice to single index is invalid.

Incorrect. Insert requires integer value and index position.

Which statement about bytearray is FALSE?

Correct! This statement is false because bytearrays are mutable.

Incorrect. This is true.

Incorrect. This is true.

Incorrect. This is true.

Given ba = bytearray(3), what are its initial contents?

Correct! Passing integer size initializes zeroed bytes buffer.

Incorrect. Initialized with null bytes (x00).

Incorrect. Size parameter creates 3 elements.

Incorrect. Size integer creates zero-filled buffer.

What is the result of len(bytearray(b"12345"))?

Correct! Length corresponds to the 5 byte elements stored.

Incorrect. Length counts element items, not total bit values.

Incorrect. Contains 5 bytes.

Incorrect. len() functions normally on bytearrays.

Can you clear all elements in a bytearray using ba.clear()?

Correct! .clear() empties mutable bytearrays.

Incorrect. Lists and bytearrays support .clear().

Incorrect. Bytearrays can grow and shrink dynamically.

Incorrect. Object remains an empty bytearray.

Question 1 of 0

23.3. Converting Between Strings and Bytes (.encode & .decode)

Converting text strings to raw binary bytes and vice versa requires explicit encoding and decoding:

  • Encoding (.encode()): Converts a human-readable text string (str) into raw binary bytes (bytes) using a specified character set (e.g., UTF-8).

  • Decoding (.decode()): Converts raw binary bytes (bytes) back into a text string (str).

  • Default Encoding: Python uses UTF-8 encoding by default if no argument is passed.

  • Type Strictness: You cannot directly concatenate a str and a bytes object without explicitly converting one first.

text = "Hello, World!"

# Encode string to bytes
binary_data = text.encode("utf-8")
print(binary_data)  # Output: b'Hello, World!'
print(type(binary_data))  # Output: <class 'bytes'>

# Decode bytes back to string
restored_text = binary_data.decode("utf-8")
print(restored_text)  # Output: Hello, World!
print(type(restored_text))  # Output: <class 'str'>

23.3.1. Quiz: Converting Between Strings and Bytes

23.3.1.1. Fill-in-the-Blanks (Cloze)

Complete the following sentences by filling in the blanks.
Word Bank (Drag items below):
.decode()
.encode()
TypeError
UTF-8
UnicodeDecodeError

1. To convert a string (`str`) into `bytes`, use the Drop here method.
2. To convert a `bytes` object back into a string (`str`), use the Drop here method.
3. The default character encoding standard used by Python is Drop here.
4. Attempting `b"Hello" + "World"` results in a Drop here.
5. Decoding binary data that contains invalid byte sequences raises a Drop here.

23.3.1.2. Code Ordering Examples

Example 1: Encode a string message and transmit/print binary output.

Drag and drop lines into the correct order and click to adjust indentation:
☰
encoded_bytes = message.encode("utf-8")
☰
message = "Python 3"
☰
print(encoded_bytes)

Example 2: Decode incoming raw network bytes into readable text.

Drag and drop lines into the correct order and click to adjust indentation:
☰
decoded_text = received_data.decode("utf-8")
☰
received_data = b"Welcome user"
☰
print(decoded_text)

Example 3: Encode, modify via bytearray, and decode back to string.

Drag and drop lines into the correct order and click to adjust indentation:
☰
raw_buffer[0] = 98
☰
original_text = "cat"
☰
raw_buffer = bytearray(original_text.encode())
☰
print(raw_buffer.decode())

23.3.1.3. Multiple Choice Questions

Progress: 0
Score: 0 / 0
Question 1 of 0

Which method converts a str object into a bytes object?

Correct! .encode() transforms text strings into binary byte representations.

Incorrect. .decode() transforms bytes into text strings.

Incorrect. .to_bytes() is used on integers.

Incorrect. No .convert() string method exists in standard Python.

Which method converts a bytes object back into a human-readable str?

Correct! .decode() converts raw binary bytes into string text.

Incorrect. .encode() goes from string to bytes.

Incorrect. Uses method call syntax .decode().

Incorrect. Python uses .decode().

What is the default encoding used when calling "hello".encode() in Python 3?

Correct! UTF-8 is the default standard encoding in Python 3.

Incorrect. UTF-8 is default, though ASCII is a subset.

Incorrect. UTF-8 is the built-in default parameter.

Incorrect. UTF-8 is standard.

What happens if you attempt to execute b"Hello " + "World"?

Correct! Cannot concatenate bytes and str objects directly.

Incorrect. Type implicit conversion does not occur automatically.

Incorrect. Raises TypeError.

Incorrect. Raises TypeError.

Given s = "Python", what is the data type of s.encode()?

Correct! Encoding a string outputs a bytes object.

Incorrect. Encoding converts from str to bytes.

Incorrect. .encode() returns immutable bytes by default.

Incorrect. Returns bytes sequence.

What error is raised when trying to decode corrupted byte sequences with .decode("utf-8")?

Correct! Invalid UTF-8 byte sequences trigger a UnicodeDecodeError.

Incorrect. Specific UnicodeDecodeError subclass is raised.

Incorrect. Decoding wrong sequence types raises UnicodeDecodeError.

Incorrect. KeyErrors occur with dictionaries.

What is the output of b"Python".decode()?

Correct! Decoding raw bytes b”Python” yields string literal “Python”.

Incorrect. .decode() strips the bytes classification and yields str.

Incorrect. Returns string object, not list.

Incorrect. Returns decoded string.

How can you fix the expression b"Data: " + "123" to avoid a TypeError?

Correct! Encoding “123” converts it to bytes, allowing binary concatenation.

Incorrect. String conversion of bytes creates “b’Data: ‘123”.

Incorrect. Cannot concatenate str and int.

Incorrect. Unsupported method call.

What parameter can be passed to .decode(errors="ignore")?

Correct! errors=”ignore” suppresses decoding errors.

Incorrect. Handled by .upper().

Incorrect. Parameter controls error handling.

Incorrect. Controls Unicode decoding error handling.

Is "A".encode("utf-8") equal to b"A" in Python?

Correct! ASCII letter ‘A’ encoded in UTF-8 yields exact byte literal b”A”.

Incorrect. Statements evaluate as equal.

Incorrect. Cross-platform behavioral consistency.

Incorrect. Expression is valid syntax.

Question 1 of 0