Bytearray
The bytearray data type is a built-in Python sequence type, similar to bytes, but mutable. It is designed to store a sequence of bytes, where each byte is an integer in the range of 0 to 255.
- bytearray is a pre-defined class treated as a sequence data type, like list, tuple, or bytes.
- It is used to represent mutable sequences of single-byte integers, often for binary data manipulation.
# Verify bytearray as a class and sequence type
l = [10, 20, 30]
ba = bytearray(l)
print("Bytearray object:", ba, type(ba)) # bytearray(b'\n\x14\x1e') <class 'bytearray'>
print("Is sequence?", isinstance(ba, (list, tuple, str, bytes, bytearray))) # True
# Iteration as a sequence
for v in ba:
print(v) # 10, 20, 30
- Stores positive integer values from 0 to 255 (256 values, as 256 - 1 = 255).
- Used for scenarios requiring modifiable binary data, such as file I/O, network protocols, or data encoding/decoding.
# Store valid byte values (0 to 255)
l = [0, 127, 255] # Minimum, middle, maximum valid values
ba = bytearray(l)
print("Valid bytearray:", ba) # bytearray(b'\x00\x7f\xff')
for v in ba:
print(v) # 0, 127, 255
# Invalid value
try:
ba = bytearray([256])
print(ba)
except ValueError as e:
print("Error:", e) # Error: bytearray must be in range(0, 256)
- Created using the bytearray() constructor, which converts an iterable of integers (or other compatible objects) into a bytearray object.
- Syntax: varname = bytearray(object)
- The input must contain integers in the range 0 to 255; otherwise, a ValueError is raised.
- Non-integer elements (e.g., strings) cause a TypeError.
# Create bytearray from different objects
l = [10, 20, 30]
ba1 = bytearray(l)
print("From list:", ba1) # bytearray(b'\n\x14\x1e')
t = (40, 50, 60)
ba2 = bytearray(t)
print("From tuple:", ba2) # bytearray(b'(:<')
s = "hi"
ba3 = bytearray(s.encode("utf-8"))
print("From string (encoded):", ba3) # bytearray(b'hi')
# No symbolic notation
try:
ba4 = bytearray[10, 20] # Incorrect syntax
except TypeError as e:
print("Error: No symbolic notation") # Error: No symbolic notation
Sequence Operations:
- Supports indexing (e.g., ba[0]) and slicing (e.g., ba[2:5]), returning individual bytes or a new bytearray.
- Maintains insertion order, preserving the order of elements from the input iterable.
# Create bytearray from different objects
l = [10, 20, 30]
ba1 = bytearray(l)
print("From list:", ba1) # bytearray(b'\n\x14\x1e')
t = (40, 50, 60)
ba2 = bytearray(t)
print("From tuple:", ba2) # bytearray(b'(:<')
s = "hi"
ba3 = bytearray(s.encode("utf-8"))
print("From string (encoded):", ba3) # bytearray(b'hi')
# No symbolic notation
try:
ba4 = bytearray[10, 20] # Incorrect syntax
except TypeError as e:
print("Error: No symbolic notation") # Error: No symbolic notation
# Insertion order preservation
l = [255, 0, 127, 10] # Specific order
ba = bytearray(l)
print("Input list:", l) # [255, 0, 127, 10]
print("Bytearray:", ba) # bytearray(b'\xff\x00\x7f\n')
# Verify order
for i, v in enumerate(ba):
print(f"Index {i}: {v}") # Index 0: 255, Index 1: 0, Index 2: 127, Index 3: 10
# Slicing retains order
print("Slice [1:3]:", ba[1:3]) # bytearray(b'\x00\x7f')
- Unlike bytes, bytearray is mutable, allowing item assignment (e.g., ba[0] = 100) at the same memory address.
# Demonstrate mutability
ba = bytearray([10, 20, 30])
print("Before:", ba, id(ba)) # bytearray(b'\n\x14\x1e') <id>
ba[0] = 100
print("After ba[0] = 100:", ba, id(ba)) # bytearray(b'd\x14\x1e') <same id>
ba[1:3] = bytearray([200, 201]) # Modify slice
print("After slice assignment:", ba, id(ba)) # bytearray(b'd\xc8\xc9') <same id>
# Invalid assignment
try:
ba[0] = 256
except ValueError as e:
print("Error:", e) # Error: bytearray must be in range(0, 256)
- Modifications do not create a new object, as confirmed by consistent id() values.
- Like bytes, bytearray has no literal syntax (e.g., no equivalent to [] for lists).
- Must use bytearray() or convert from bytes (e.g., bytearray(b"data")).
# Compare bytearray and bytes
l = [10, 20, 30]
ba = bytearray(l)
b = bytes(l)
print("Bytearray:", ba, type(ba)) # bytearray(b'\n\x14\x1e') <class 'bytearray'>
print("Bytes:", b, type(b)) # b'\n\x14\x1e' <class 'bytes'>
# Sequence operations (same)
print("ba[0] == b[0]:", ba[0] == b[0]) # True (both 10)
print("ba[1:3] vs b[1:3]:", ba[1:3], b[1:3]) # bytearray(b'\x14\x1e') b'\x14\x1e'
# Mutability difference
ba[0] = 100
print("Modified bytearray:", ba) # bytearray(b'd\x14\x1e')
try:
b[0] = 100
except TypeError as e:
print("Bytes Error:", e) # Error: 'bytes' object does not support item assignment