Lesson 11 · Python data types deep dive
Python Bytes Explained: Binary Data, Encoding & Decoding | Data Types #11
Video eleven of the twelve-part series: bytes, Python's immutable sequence of raw binary data. Construction, indexing, the text-binary boundary, and all…
- CoursePython data types deep dive
- Lesson11 of 12
- Video28 min
- FormatJupyter notebook · 23 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbPython Data Types Deep-Dive, Video 11: Bytes (bytes)#
- Video eleven of the twelve-part series: bytes, Python's immutable sequence of raw binary data.
- Construction, indexing, the text-binary boundary, and all forty-two public bytes methods.
- Let's get into it.
Part 1: What Makes bytes Different#
data = b'hello'
print(type(data))
print(len(data))
print(data[0])
print(list(data))
Part 2: Bytes Literals and Construction#
literal = b'hello world'
empty = b''
also_empty = bytes()
from_ints = bytes([72, 101, 108, 108, 111])
zero_filled = bytes(5)
from_string = bytes('hello', encoding='utf-8')
print(literal, empty, from_ints, zero_filled, from_string)
try:
bytes('hello')
except TypeError as e:
print(f'Caught: {e}')
hex_string = '48656c6c6f'
from_hex = bytes.fromhex(hex_string)
print(from_hex)
print(from_hex.hex())
Part 3: Indexing and Slicing#
data = b'python'
print(data[0])
print(data[0:1])
print(type(data[0]))
print(type(data[0:1]))
print(data[1:4])
print(data[::-1])
Part 4: decode() and the Text-Binary Boundary#
raw = b'caf\xc3\xa9'
text = raw.decode('utf-8')
print(text)
print(type(text))
print(raw.decode('utf-8', errors='replace'))
try:
raw.decode('ascii')
except UnicodeDecodeError as e:
print(f'Caught: {e}')
Part 5: hex() and fromhex() in Practice#
mac_bytes = bytes([0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E])
print(mac_bytes.hex())
print(mac_bytes.hex(':'))
print(mac_bytes.hex('-', 1))
import hashlib
digest = hashlib.sha256(b'hello world').digest()
print(digest.hex())
Part 6: Case-Changing Methods#
text = b'the Quick BROWN fox'
print(text.upper())
print(text.lower())
print(text.capitalize())
print(text.title())
print(text.swapcase())
Part 7: Case-Checking Methods#
print(b'HELLO'.isupper())
print(b'Hello'.isupper())
print(b'hello'.islower())
print(b'Hello World'.istitle())
print(b'123'.isupper())
Part 8: Padding: center, ljust, rjust, zfill#
word = b'hi'
print(word.center(10, b'*'))
print(word.ljust(10, b'.'))
print(word.rjust(10, b'.'))
print(b'42'.zfill(5))
print(b'-42'.zfill(5))
Part 9: Stripping: strip, lstrip, rstrip#
messy = b' padded '
print(messy.strip())
print(messy.lstrip())
print(messy.rstrip())
print(b'xxxhelloxxx'.strip(b'x'))
Part 10: Searching: find, rfind, index, rindex#
data = b'the quick brown fox'
print(data.find(b'quick'))
print(data.find(b'slow'))
print(data.rfind(b'o'))
print(data.index(b'brown'))
try:
data.index(b'slow')
except ValueError as e:
print(f'Caught: {e}')
Part 11: count, startswith, endswith#
data = b'mississippi'
print(data.count(b's'))
print(data.count(b'ss'))
filename = b'archive.tar.gz'
print(filename.startswith(b'archive'))
print(filename.endswith(b'.gz'))
print(filename.endswith((b'.gz', b'.zip', b'.tar')))
Part 12: Splitting: split, rsplit, splitlines, partition, rpartition#
csv_row = b'apple,banana,cherry,date'
print(csv_row.split(b','))
print(csv_row.split(b',', 2))
print(csv_row.rsplit(b',', 1))
print(b' spaced words '.split())
multiline = b'line one\nline two\r\nline three'
print(multiline.splitlines())
print(multiline.splitlines(keepends=True))
email = b'user@example.com'
print(email.partition(b'@'))
print(email.rpartition(b'@'))
Part 13: join()#
parts = [b'the', b'quick', b'brown', b'fox']
print(b' '.join(parts))
print(b','.join(parts))
print(b''.join(parts))
Part 14: replace()#
data = b'the cat sat on the mat'
print(data.replace(b'the', b'THE'))
print(data.replace(b'the', b'THE', 1))
Part 15: Character Classification Methods#
print(b'Python3'.isalnum())
print(b'Python 3'.isalnum())
print(b'Python'.isalpha())
print(b'123'.isdigit())
print(b' '.isspace())
print(b'hello'.isascii())
print(bytes([200]).isascii())
Part 16: translate() and maketrans()#
table = bytes.maketrans(b'aeiou', b'AEIOU')
print(b'the quick brown fox'.translate(table))
delete_table = bytes.maketrans(b'', b'')
print(b'the quick brown fox'.translate(delete_table, delete=b'aeiou'))
Part 17: expandtabs()#
row = b'name\tage\tcity'
print(repr(row.expandtabs()))
print(repr(row.expandtabs(4)))
Part 18: removeprefix() and removesuffix()#
filename = b'IMG_final.png'
print(filename.removeprefix(b'IMG_'))
print(filename.removeprefix(b'nope_'))
print(filename.removesuffix(b'.png'))
Part 19: Immutability in Practice#
data = b'hello'
try:
data[0] = 72
except TypeError as e:
print(f'Caught: {e}')
new_data = bytes([72]) + data[1:]
print(new_data)
Part 20: Common Patterns#
with open('binary_demo.bin', 'wb') as f:
f.write(b'\x00\x01\x02\x03hello')
with open('binary_demo.bin', 'rb') as f:
contents = f.read()
print(contents)
print(type(contents))
import struct
packed = struct.pack('>I', 1024)
print(packed)
print(packed.hex())
unpacked = struct.unpack('>I', packed)
print(unpacked)
Wrap-Up: What You Learned#
- bytes is an immutable sequence of integers 0-255, representing raw binary data.
- Construction from literals, iterables of ints, zero-fill, and fromhex; indexing returns int, slicing returns bytes.
- decode() bridges bytes back to str; hex() and fromhex() bridge bytes to readable hex text.
- Case methods, padding, stripping, searching, splitting, joining, and replacing, all mirroring str's behavior on raw bytes.
- Five ASCII-only classification methods, translate/maketrans, expandtabs, removeprefix, removesuffix.
- Immutability, and real patterns: binary file I/O and the struct module.
- That's all forty-two public bytes methods covered. Next up: bytearray, bytes' mutable sibling.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



