The array module provides a mutable sequence of numeric values stored in a compact representation. Unlike a list, which stores references to Python objects, an array.array keeps elements of one C-compatible type in contiguous memory. This reduces overhead and makes it easier to exchange data with binary files, sockets, and APIs that support the buffer protocol.
The module is not a replacement for NumPy when you need vectorized computation, linear algebra, or multidimensional arrays. It is useful when a standard-library structure with homogeneous types, predictable memory use, and list-like methods is enough.
Create an array
The first argument is a typecode that selects the element type.
from array import array
values = array("i", [10, 20, 30])
print(values)
print(values.itemsize)
The size and range of selected typecodes depend on the platform. Inspect itemsize when the binary layout matters.
Common typecodes
Frequently used codes include b/B for signed and unsigned bytes, h/H for short values, i/I for integers, l/L for long values, q/Q for 64-bit integers, f for float, and d for double.
Choose the smallest type that safely covers the domain. Out-of-range values cannot be inserted.
List-like operations
Arrays support indexing, slices, append(), extend(), insert(), pop(), remove(), reverse(), and counting.
values.append(40)
values.extend([50, 60])
print(values[1:4])
Every inserted value must be compatible with the typecode.
Convert to a list
tolist() creates normal Python objects.
items = values.tolist()
The conversion copies data and loses the compact representation. Perform it only at an API boundary that requires a list.
Create from bytes
frombytes() appends values by interpreting a binary block.
data = (1).to_bytes(4, "little") + (2).to_bytes(4, "little")
values = array("I")
values.frombytes(data)
The interpretation uses the native layout of the type and platform. Use struct or explicit byte-order normalization for portable protocols.
Convert to bytes
tobytes() returns the native binary representation.
payload = values.tobytes()
The result does not include a typecode, count, byte order, or version. The reader must know the contract separately.
Byte order
byteswap() reverses the byte order of each element when supported.
values.byteswap()
Call it only when you know the source and target byte order. Calling it twice restores the original representation.
Read from a file
fromfile() reads a requested number of elements from a binary file.
values = array("d")
with open("measurements.bin", "rb") as file:
values.fromfile(file, 100)
If the file ends early, some elements may be appended before EOFError is raised. Handle partial state.
Write to a file
tofile() writes the native representation.
with open("measurements.bin", "wb") as file:
values.tofile(file)
For durable formats, add a header containing magic bytes, version, typecode, byte order, and count.
When to use struct
struct is better for records containing fields of different types.
Use Python struct for heterogeneous layouts and array for long homogeneous sequences.
The buffer protocol
An array can be exposed through memoryview without copying.
values = array("I", range(100))
view = memoryview(values)
try:
consume(view)
finally:
view.release()
Do not resize an array while exported views exist.
readinto and direct I/O
APIs that accept mutable buffers can fill an array directly.
values = array("B", [0]) * 4096
with open("data.bin", "rb") as file:
count = file.readinto(values)
The return value is the number of bytes read. Handle partial reads correctly.
Slices
An array slice creates another array with the same typecode.
part = values[10:20]
This copies elements. Use memoryview for a zero-copy view.
Repetition
Like lists, arrays can be repeated.
zeros = array("f", [0.0]) * 1000
Huge multipliers can exhaust memory. Validate external sizes.
Memory use
The savings come from storing each element in its C representation without a separate Python integer or float object.
Measure realistic workloads. Very small arrays may not justify added complexity.
Performance
Python loops over an array still execute one element at a time. Compact storage does not automatically provide vectorization.
NumPy is usually better for intensive numerical transformations. array can be ideal for storage and I/O.
Unicode values
Historical Unicode-related typecodes have portability limitations. Prefer str, explicitly encoded bytes, or standard codecs for text.
Do not design a portable text format around a native character array without a precise contract.
Overflow validation
Inserting an integer outside the typecode range raises OverflowError.
try:
values.append(number)
except OverflowError as error:
raise ValueError("value is outside the allowed range") from error
Validate units and limits before insertion.
Concurrency
An array is mutable and does not provide synchronization. Threads that write or resize the same object need a lock.
For sharing across processes, use shared memory or a memory-mapped file with an explicit synchronization protocol.
Integration with mmap
A memoryview over an mmap can be consumed by buffer-aware code. Copy into an array when independent ownership is more important.
See Python mmap.
Serialization
Do not treat tobytes() alone as a self-describing format. Include metadata or use a documented standard.
For cross-machine exchange, define element size, signedness, and byte order explicitly.
Security
Apply limits before allocating an array from an external count. Check that payload length is a multiple of itemsize.
if len(payload) % values.itemsize != 0:
raise ValueError("truncated payload")
if len(payload) > BYTE_LIMIT:
raise ValueError("payload is too large")
Testing
Test minimum and maximum values, byte order, truncated files, partial reads, empty arrays, slices, active memoryviews, and platform differences.
Verify interoperability with known binary vectors.
Common mistakes
Common failures include assuming every typecode has the same size on every platform, writing raw bytes without a header, confusing compact storage with vectorized math, resizing while a view is active, ignoring partial reads, and selecting a type that is too small.
Conclusion
array provides homogeneous compact numeric sequences using only the standard library. It combines a familiar interface with binary files and the buffer protocol.
Choose typecodes carefully, document byte order, and use NumPy when advanced numerical operations are required. Consult the official array documentation, Python struct, and Python mmap.







