Lesson 07
bytearray — Mutable Byte Sequence
Understand mutable binary data, modify bytes in place, compare bytes with bytearray, and learn when each should be used in real applications.
Visual reference
What you will learn
- Mutable bytes — edit binary data directly
- 0–255 rule — same valid range as
bytes - In-place updates — change values without a new object
bytesvsbytearray— when to use each
Chapter 1 — Why do we need bytearray?
In the previous lesson, bytes is immutable: you can read binary data, but you cannot change it in place.
bytes |
bytearray |
|
|---|---|---|
| Analogy | Sealed PDF — read only | Word document — editable |
| Image |
Use bytearray when you need a buffer you can rewrite — for example while building or patching binary payloads before sending them over a network.
Chapter 2 — What is bytearray?
bytearray is a pre-defined sequence type for mutable binary data.
Purpose (your notes): same networking / encryption context as bytes — values in [0, 256) i.e. 0–255.
Definition: an ordered collection of integers 0–255 whose elements can be modified.
Syntax: varname = bytearray(object) — usually a list of integers.
Note from your notes: functionality is almost the same as bytes, but bytes is immutable and bytearray is mutable (item assignment allowed).
Chapter 3 — Creating a bytearray
numbers = [100, 0, 150, 255, 34, 156, 23]
ba = bytearray(numbers)
print(ba)
print(type(ba))bytearray(b'd\x00\x96\xff"\x9c\x17')
<class 'bytearray'>Looks like bytes, but the type is bytearray.
Chapter 4 — Valid value range
Every element must satisfy 0 ≤ value ≤ 255.
- Valid:
0,1,128,255 - Invalid:
-1,256,500
From your notes:
# bytearray([100, 150, 256])
# ValueError: byte must be in range(0, 256)
# bytearray([100, 0, 150, 255, -34, 156, 23])
# ValueError: byte must be in range(0, 256)Same validation as bytes().
Chapter 5 — Indexing and slicing
Insertion order is preserved — indexing and slicing work like bytes.
ba = bytearray([100, 0, 150, 255, 34])
print(ba[0])
print(ba[-1])
print(ba[0:4])100
34
bytearray(b'd\x00\x96\xff')Your notes: ba[0:4] prints the same byte pattern as the bytes lesson, but type is bytearray.
Chapter 6 — The biggest difference: mutability
ba = bytearray([100, 0, 150])
ba[0] = 125Before: [100, 0, 150] → After: [125, 0, 150]
Only the contents change — the same object is updated.
Interactive editing in the playground
Change ba[0] = 125, edit other indices, or run the flip example in the starter code. Compare id(ba) before and after — it stays the same.
Chapter 7 — Does id() change?
ba = bytearray([1, 2, 3])
print(id(ba))
ba[0] = 99
print(id(ba))The two id() values match (your notes show the same id 2947700805488 before and after ba[0] = 125).
Chapter 8 — bytes vs bytearray
| Feature | bytes |
bytearray |
|---|---|---|
| Mutable? | No | Yes |
| Value range | 0–255 | 0–255 |
| Indexing / slicing | Yes | Yes |
| Item assignment | TypeError | Allowed |
| Best for | Read-only payloads | Editable buffers |
# b = bytes([65, 66])
# b[0] = 90 # TypeError
ba = bytearray([65, 66])
ba[0] = 90 # OKChapter 9 — Real-world use cases
Image editing — change pixel bytes in a buffer
Video streaming — update frame buffers
Networking — patch packet fields before send
Cryptography — work on byte buffers in place (then often freeze to bytes)
Practice exercise
Flip the first and last byte of [10, 20, 30, 40]:
ba = bytearray([10, 20, 30, 40])
ba[0] = 40
ba[3] = 10
print(list(ba))[40, 20, 30, 10]Quick knowledge check
-
What makes
bytearraydifferent frombytes?
It is mutable (item assignment allowed). -
Does
ba[0] = 125create a new object?
No — same object, updated contents. -
Which constructor is mutable?
bytearray().
Summary
bytearraystores 0–255 likebytes, but allows in-place changes.- Supports indexing, slicing, and iteration; assignment updates the buffer.
id()usually stays the same afterba[i] = ....- Use
bytesfor fixed data;bytearrayfor editable binary buffers.
Next lesson: range — numeric sequences with start, stop, and step.
Loading playground…