Python's built-in array module provides space-efficient storage of basic C-like data types:
from array import array
# 'i' = signed int, 'f' = float, 'd' = double, 'u' = unicode char
numbers = array('i', [1, 2, 3, 4, 5])
print(numbers) # array('i', [1, 2, 3, 4, 5])
| Code | C Type | Python Type | Min Size |
|---|---|---|---|
'b' | signed char | int | 1 byte |
'B' | unsigned char | int | 1 byte |
'h' | signed short | int | 2 bytes |
'i' | signed int | int | 2-4 bytes |
'f' | float | float | 4 bytes |
'd' | double | float | 8 bytes |
Arrays support the same indexing and slicing syntax as lists:
arr = array('i', [10, 20, 30, 40, 50])
arr[0] # 10
arr[-1] # 50
arr[1:3] # array('i', [20, 30])
arr[::2] # array('i', [10, 30, 50])
arr[0] = 99 # mutable: [99, 20, 30, 40, 50]
arr = array('f', [1.5, 2.5, 3.5])
for val in arr:
print(val)
for i, val in enumerate(arr):
print(i, val)
squared = [x ** 2 for x in arr] # list comprehension
arr = array('i', [1, 2, 3])
arr.append(4) # [1, 2, 3, 4]
arr.extend([5, 6]) # [1, 2, 3, 4, 5, 6]
arr.insert(0, 0) # [0, 1, 2, 3, 4, 5, 6]
arr = array('i', [1, 2, 3, 4, 5, 3])
arr.pop() # removes & returns 5
arr.pop(0) # removes & returns 1
arr.remove(3) # removes first occurrence of 3
# arr.remove(99) # ValueError
arr.clear() # empties array
arr = array('i', [3, 1, 4, 1, 5, 9, 2])
# Arrays don't have a .sort() method
sorted_arr = array('i', sorted(arr))
print(sorted_arr) # array('i', [1, 1, 2, 3, 4, 5, 9])
# Reverse in place
arr.reverse()
print(arr)
# Copy
shallow = arr[:] # slice copy
from copy import copy
shallow2 = copy(arr) # shallow copy
deep = arr.__copy__() # also shallow
| Feature | array | list |
|---|---|---|
| Type constraint | Single type | Any type |
| Memory | Compact (C-level) | Larger (PyObject*) |
| Flexibility | Limited methods | Rich methods |
| Comprehensions | Via list then convert | Built-in |
| Performance | Faster for homogeneous numeric data | More overhead per element |
array when you need to store a large number of numeric values of the same type and memory efficiency matters. For most general-purpose work, lists are more flexible and idiomatic.
from array import array
# Store sensor readings efficiently
readings = array('d', [22.5, 23.1, 21.8, 24.0, 22.9])
mean = sum(readings) / len(readings)
variance = sum((x - mean) ** 2 for x in readings) / len(readings)
std_dev = variance ** 0.5
print(f"Mean: {mean:.2f}, Std Dev: {std_dev:.2f}")
# Write to binary file
with open("readings.bin", "wb") as f:
readings.tofile(f)
# Read back
restored = array('d')
with open("readings.bin", "rb") as f:
restored.fromfile(f, 5)
print(restored) # array('d', [22.5, 23.1, 21.8, 24.0, 22.9])
numpy.ndarray), which is far more powerful than the built-in array module. The array module is best for simple typed storage without external dependencies.
Create an array of 20 random integers between 0 and 100. Write code to: (1) find the minimum, maximum, and average values, (2) create a new array containing only values above the average, (3) remove all odd values from the original array, (4) sort the original array in ascending order using sorted(), and (5) write the sorted array to a binary file and read it back. Compare the memory usage with an equivalent list using sys.getsizeof().