Python array: Compact Numeric Data

Published on: August 10, 2026
Reading time: 6 minutes
Monitor with binary data representing compact numeric arrays in Python

Python lists are flexible, readable, and appropriate for most application code. However, they are not always the best representation for hundreds of thousands of numbers that all share the same machine type. The standard-library Python array module stores homogeneous numeric values in a compact contiguous block. Each item uses a fixed binary representation selected by a type code, which can reduce memory use and simplify integration with files, buffers, and lower-level APIs.

The module is intentionally small. It does not replace NumPy for scientific computing, multidimensional data, broadcasting, or vectorized mathematics. Its strength is providing a dependency-free numeric container with familiar sequence operations and direct binary conversion.

This guide complements our articles about bisect, mmap, shelve, filecmp, and NumPy.

When an array is useful

Use array.array when every element is compatible with the same C numeric type and you need a mutable sequence that is denser than a normal list. Typical examples include sensor samples, audio values, counters, indexes, coordinates, binary records, and chunks received from a network service.

A list stores references to Python objects. An array stores the values directly. The exact memory advantage depends on the type code, platform, allocator, and list contents, so benchmark the real workload rather than assuming a fixed saving.

Create an array

from array import array

values = array("i", [10, 20, 30, 40])
print(values)
print(values[0])

The first argument is the type code. Here, i means a signed C integer. Its exact byte width can be platform dependent, so inspect itemsize when a binary format requires a known representation.

Important type codes

Common integer codes include b and B for one-byte signed and unsigned values, h and H for short integers, i and I for integers, and q and Q for 64-bit values where supported. Floating-point data normally uses f or d.

Do not choose a code only because its name looks appropriate. Verify sign, range, and itemsize. Appending an out-of-range integer raises OverflowError, which protects the program from silent truncation.

Add and remove elements

data = array("H")
data.append(100)
data.extend([200, 300, 400])
data.insert(1, 150)

last = data.pop()
data.remove(200)

The API resembles a list. It supports append, extend, insert, pop, remove, reverse, count, and index. Every inserted element must be valid for the selected type.

Indexing and slicing

samples = array("h", [2, 4, 6, 8, 10])
print(samples[1:4])
samples[1:3] = array("h", [40, 60])

A slice produces another array with the same type code. Slice assignment also expects a compatible array. That restriction prevents accidental mixing of binary representations.

Measure storage

values = array("d", [1.5, 2.5, 3.5])
print(values.itemsize)
print(len(values) * values.itemsize)

The multiplication gives the bytes occupied by the elements, excluding the small container overhead. Comparing this number with sys.getsizeof() on a list requires care because a list’s reported size does not include every referenced numeric object.

Convert to and from lists

regular_list = values.tolist()
more = array("d")
more.fromlist([4.5, 5.5])

tolist() is useful when another API expects normal Python objects. fromlist() validates incoming elements before adding them. When handling untrusted application input, perform explicit conversion and range checks before passing values to the array.

Convert to bytes

numbers = array("I", [1, 2, 3])
block = numbers.tobytes()

copy = array("I")
copy.frombytes(block)

tobytes() exports the native in-memory representation. frombytes() requires a byte count divisible by itemsize. Reject malformed lengths early instead of letting an invalid network packet or file fragment reach later processing.

Byte order and portability

The bytes produced by an array normally use the host machine’s native byte order. A file created on a little-endian machine may be interpreted differently on a big-endian machine.

import sys

if sys.byteorder != "little":
    numbers.byteswap()

byteswap() reverses the byte order inside each element. Long-lived formats and network protocols should explicitly define their byte order. Record the type width as well; a vague statement such as “native integer” is not a portable format specification.

Read and write binary files

data = array("f", [0.5, 1.5, 2.5])

with open("samples.bin", "wb") as file:
    data.tofile(file)

loaded = array("f")
with open("samples.bin", "rb") as file:
    loaded.fromfile(file, 3)

fromfile() receives an item count, not a byte count. If the file ends early, it raises EOFError, but some items may already have been appended. Applications should validate the expected file length and discard partial state when completeness is mandatory.

Use the buffer protocol

Arrays implement Python’s buffer protocol, allowing a memoryview to access their storage without copying.

values = array("i", [10, 20, 30])
view = memoryview(values)
print(view.format, view.itemsize)
view[0] = 99

The assignment updates the original array. While a view exports its buffer, operations that resize the array may fail. Release or delete views before appending, inserting, or otherwise changing the storage size.

Interoperate without extra copies

Many native extensions, compression functions, hashing APIs, sockets, and system calls accept buffer-compatible objects. Passing an array directly can avoid an intermediate conversion to bytes.

Buffer compatibility does not guarantee semantic compatibility. The receiving API must agree on item width, alignment, signedness, byte order, and total length. Document those properties at every integration boundary.

Validate numeric ranges

small = array("B")
small.append(255)
# small.append(256)  # OverflowError

Validate user-controlled values before insertion. For integer arrays, check lower and upper bounds. For floating-point arrays, decide how the application handles NaN, infinity, negative zero, and precision loss.

Array versus list

Choose a list for heterogeneous objects, nested application structures, or code where flexibility and readability matter more than memory density. Choose an array for homogeneous numeric values, binary interoperability, or a compact mutable buffer.

An array does not automatically make Python loops faster. A loop that sums or transforms elements still runs Python-level operations unless another native API processes the buffer.

Array versus NumPy

NumPy supports multidimensional arrays, many data types, broadcasting, linear algebra, vectorized functions, and an extensive scientific ecosystem. The standard array module is smaller, available without installation, and appropriate for straightforward one-dimensional storage.

For numerical analysis, images, matrices, or large transformations, NumPy is usually the better tool. For a command-line utility, compact protocol field, or small binary reader, array may be all that is needed.

Mutation and concurrency

Arrays are mutable and do not provide high-level synchronization. Multiple threads or processes modifying shared data require locks or a carefully designed protocol. A memoryview does not make a multi-step update atomic.

Common mistakes

  • Selecting a type code without checking itemsize.
  • Writing native-endian data into a format that requires fixed endianness.
  • Confusing items with bytes.
  • Appending numbers outside the valid range.
  • Resizing while exported memory views are alive.
  • Expecting NumPy-style vectorized operations.
  • Trusting an external binary block without checking size and format.

Practical checklist

  • Document type code, signedness, width, and byte order.
  • Validate numeric ranges before insertion.
  • Use context managers for files.
  • Check that byte lengths are multiples of itemsize.
  • Release views before resizing.
  • Benchmark memory and speed with realistic data.
  • Move to NumPy when vectorized computation becomes important.

Conclusion

The Python array module provides compact homogeneous numeric sequences with a familiar mutable interface. It can convert directly to bytes, read and write binary files, and expose storage through the buffer protocol.

Safe use depends on selecting the correct type, validating ranges, and defining a portable binary representation. See the official array documentation and the buffer protocol documentation for complete details.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Color wheel representing RGB, HSV, and HLS conversions with Python colorsys
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python colorsys: RGB, HSV, and HLS

    Learn Python colorsys to convert colors between RGB, HSV, HLS, and YIQ, generate palettes, and avoid scale and precision mistakes.

    Ler mais

    Tempo de leitura: 5 minutos
    09/08/2026
    Configuration icon representing plist files with Python plistlib
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python plistlib: Apple Plist Files

    Learn Python plistlib to read and write XML and binary plist files, validate data, handle dates, bytes, and UIDs safely.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Digital padlock representing host credentials with Python netrc
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python netrc: Credentials by Host

    Learn Python netrc to read credentials by host, validate permissions, handle parse errors, and integrate network clients safely.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Digital message representing quoted-printable encoding with Python quopri
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python quopri: Quoted-Printable

    Learn Python quopri to encode and decode quoted-printable data in email, files, and MIME integrations safely.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Digital file icon representing MIME types with Python mimetypes
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python mimetypes: MIME Types

    Learn Python mimetypes to identify MIME types, extensions, and encodings safely in uploads, downloads, email, and web APIs.

    Ler mais

    Tempo de leitura: 6 minutos
    08/08/2026
    Binary search and sorted lists with Python bisect
    Libraries and Modules
    Foto de perfil de Leandro Hirt da Academify

    Python bisect: Search Sorted Lists

    Learn Python bisect for binary search, ordered insertion, duplicate ranges, thresholds, and safe sorted-list design.

    Ler mais

    Tempo de leitura: 4 minutos
    08/08/2026