Python Basics: Keeping Numeric Samples in an array
A series of measurements often contains one kind of number. Python’s standard-library array module stores these values in a compact numeric sequence. It is useful when you want ordinary sequence operations with a specific storage type.
Before you start
These three independent scripts were tested on Linux with Bash, Python 3.12.14 and Python 3.13.5. No extra packages or environment variables are needed. Commands use python3; substitute python3.13 to run the other tested interpreter.
Create a fresh working directory and keep this Bash session open:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Save each UTF-8 source block below here using its stated filename. Avoid array.py, which would shadow the standard-library module. The scripts print results without creating data files or accessing the network.
Add and inspect measurements
Save as demo_array_samples.py:
from array import array
samples = array("d", [18.5, 19.0, 20.5])
samples.append(21.0)
samples.extend([22.0, 23.0])
print("Samples:", samples.tolist())
print("Last three:", samples[-3:].tolist())
print("Mean:", sum(samples) / len(samples))
for readings in (samples, array("d")):
if readings:
print("Maximum:", max(readings))
else:
print("No samples yet")Run it:
python3 demo_array_samples.pyOutput:
Samples: [18.5, 19.0, 20.5, 21.0, 22.0, 23.0]
Last three: [21.0, 22.0, 23.0]
Mean: 20.666666666666668
Maximum: 23.0
No samples yetThe "d" type code selects C double storage. Slicing returns another array; tolist() makes the displayed values familiar. Check for an empty collection before taking its maximum or dividing by its length. Floating-point rounding still applies.
Reject unsuitable values
Save as demo_array_bounds.py:
from array import array
levels = array("B", [0, 128, 255])
for value in (-1, 256, "bright"):
try:
levels.append(value)
except (OverflowError, TypeError) as error:
print(f"Rejected {value!r}: {type(error).__name__}")
levels[1:2] = array("B", [64, 192])
print("Levels:", levels.tolist())
try:
levels[0:1] = [32]
except TypeError:
print("Slice replacement needs an array with the same type code")Run it:
python3 demo_array_bounds.pyOutput:
Rejected -1: OverflowError
Rejected 256: OverflowError
Rejected 'bright': TypeError
Levels: [0, 64, 192, 255]
Slice replacement needs an array with the same type codeOn the tested Linux systems, "B" stores unsigned bytes from 0 to 255. These deliberately caught errors demonstrate bounds and type checks. They do not end the script. Slice assignment also requires a matching array type, even when a plain list contains valid integers.
Round-trip an in-memory buffer
Save as demo_array_buffer.py:
from array import array
original = array("h", [-100, 0, 100])
payload = original.tobytes()
restored = array("h")
restored.frombytes(payload)
print("Restored:", restored.tolist())
print("Equal:", restored == original)
print("Payload size matches:", len(payload) == len(original) * original.itemsize)
restored.frombytes(payload)
print("Loading again appends:", restored.tolist())
try:
array("h").frombytes(b"\x00")
except ValueError:
print("Rejected: incomplete item")Run it:
python3 demo_array_buffer.pyOutput:
Restored: [-100, 0, 100]
Equal: True
Payload size matches: True
Loading again appends: [-100, 0, 100, -100, 0, 100]
Rejected: incomplete item"h" uses signed short storage. frombytes() appends to its target, so start with an empty array for a fresh copy. A buffer must contain whole items. These array operations use native machine representation; itemsize reports bytes per item.
This round-trip stays in one process. A raw payload carries no type code, item size, or byte-order metadata. For a portable binary file or network format, define that information explicitly, for example with struct. For readable interchange, consider CSV or JSON.
Choose an array deliberately
A list is convenient when values have mixed types. An array is worth considering for a homogeneous numeric buffer. Its + operator joins sequences and * repeats them; neither performs element-by-element arithmetic. Use a comprehension for a small transformation, or evaluate a numerical library when you need larger calculations.
Clean up
In the same Bash session, remove only the scripts and the empty working directory:
rm -- demo_array_samples.py demo_array_bounds.py demo_array_buffer.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect what remains rather than deleting it recursively.
References
Acknowledgements
This post was created with assistance from AI.