Python array: Compact Numeric Data

Published on: August 28, 2026
Reading time: 4 minutes
Detailed shot of a yellow measuring tape with numbers on a dark background.

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.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Detailed view of programming code in a dark theme on a computer screen.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python struct: Binary Data Formats

    Learn Python struct for binary packing, endianness, offsets, padding, buffers, sockets, versioned layouts, and safe validation.

    Ler mais

    Tempo de leitura: 5 minutos
    28/08/2026
    Composition of black and white photos and old travel log placed with vintage island map and obsolete photo camera on narrow wooden table
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python mmap: Memory-Mapped Files

    Learn Python mmap for memory-mapped files, byte searches, in-place edits, shared pages, aligned offsets, and safe synchronization.

    Ler mais

    Tempo de leitura: 6 minutos
    28/08/2026
    Close-up of a USB pen drive being inserted into a laptop USB port on a white surface.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python importlib.metadata: Versions and Plugins

    Learn Python importlib.metadata to query versions, requirements, files, distributions, entry points, and plugins without importing packages.

    Ler mais

    Tempo de leitura: 9 minutos
    27/08/2026
    Detailed view of programming code in a dark theme on a computer screen.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    importlib.resources: Read Packaged Files

    Learn Python importlib.resources to read templates and package data with Traversable, files, and as_file across wheels, ZIPs, and frozen apps.

    Ler mais

    Tempo de leitura: 7 minutos
    27/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python runpy: Execute Modules and Scripts

    Learn Python runpy to execute modules and scripts, control __main__, run_path, alter_sys, namespaces, testing, and process isolation.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python pkgutil: Discover Packages

    Learn Python pkgutil to list modules, walk packages, discover plugins, inspect importers, and read package resources safely.

    Ler mais

    Tempo de leitura: 6 minutos
    27/08/2026