Technology  /  Python

🐍 Python 78 guides · updated 2026

From first variable to OOP, generators, and real projects — the language that runs everything from data pipelines to AI agents, taught the practical way.

Python Lists vs Arrays: Choosing the Right Sequence for Your Data

Python does not have a single “array” type. When people say “array”, they might mean a Python list, the array.array from the standard library, or a NumPy ndarray. Each has a different purpose and different trade-offs.

Key Differences at a Glance

Propertylistarray.arraynumpy.ndarray
Element typesMixedSingle typedSingle typed
Memory layoutPointers to objectsRaw valuesRaw values
Random accessO(1)O(1)O(1)
Numeric computationSlowMediumFast
Built-inYesYesNo (numpy)

Python Lists: Flexible by Design

A Python list stores references to objects. Any object can be an element — integers, strings, other lists, None, or custom class instances.

# Lists handle mixed types naturally
record = [42, "Alice", True, None, [1, 2, 3]]
print(record[1]) # "Alice"
record.append({"role": "admin"}) # no restriction on type
# Common list operations
numbers = [5, 3, 8, 1, 9, 2]
numbers.sort() # in-place: [1, 2, 3, 5, 8, 9]
subset = numbers[2:5] # slicing: [3, 5, 8]
numbers.insert(0, 0) # insert at index
numbers.remove(8) # remove first occurrence
print(numbers)

Lists are the default Python sequence. Use them unless you have a specific reason to use something else.

array.array: Compact Typed Storage

The array module provides a typed array that stores raw values without per-element object overhead. All elements must share the same type, specified by a type code.

import array
# 'i' = signed int, 'd' = double, 'f' = float, 'B' = unsigned byte
readings = array.array('d', [3.14, 2.71, 1.41, 1.73])
print(readings[0]) # 3.14
readings.append(0.57) # still mutable
# Will reject wrong type
try:
readings.append("text")
except TypeError as e:
print(f"Rejected: {e}")
# Read/write raw binary — useful for binary file I/O
with open("sensor_data.bin", "wb") as f:
readings.tofile(f)
recovered = array.array('d')
with open("sensor_data.bin", "rb") as f:
recovered.fromfile(f, len(readings))
print(list(recovered))

Use array.array when you need compact storage for large sequences of numeric values and do not want a NumPy dependency.

NumPy Arrays: Vectorised Computation

NumPy ndarray is the right choice when you do any mathematical work on arrays. Operations are implemented in C and execute without Python interpreter overhead on each element.

import numpy as np
# Create from list
arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
# Vectorised operations — no loop needed
print(arr * 2) # [2. 4. 6. 8. 10.]
print(arr ** 2) # [1. 4. 9. 16. 25.]
print(np.sqrt(arr)) # [1. 1.41 1.73 2. 2.23]
# Multi-dimensional arrays
matrix = np.zeros((3, 3))
matrix[1, 1] = 1.0 # set centre element
print(matrix)
# Specify dtype explicitly
uint8_arr = np.array([255, 128, 64], dtype=np.uint8)
print(uint8_arr.nbytes) # 3 bytes — 1 byte per element

Practical Decision Guide

# Use list when:
config_values = ["localhost", 5432, False] # mixed types
queue = [] # will grow/shrink dynamically
matrix_of_lists = [[1, 2], [3, 4], [5, 6]] # nested structure
# Use array.array when:
import array
# — storing thousands of ints/floats, memory matters, no numpy
temperature_log = array.array('f', [36.6, 37.1, 36.8, 37.4])
# Use numpy when:
import numpy as np
# — any numeric computation, matrix operations, statistics
prices = np.array([100.0, 101.5, 99.8, 103.2])
returns = np.diff(prices) / prices[:-1] # percentage changes
print(f"Mean return: {returns.mean():.4f}")

Type Codes for array.array

CodeC typeBytesPython type
'b'signed char1int
'B'unsigned char1int
'h'signed short2int
'H'unsigned short2int
'i'signed int2+int
'l'signed long4+int
'f'float4float
'd'double8float

Common Mistake: Using list.pop(0) for Queue Operations

This is a performance issue that looks like an array issue:

# SLOW: list.pop(0) is O(n) — shifts all remaining elements
queue = list(range(10_000))
while queue:
item = queue.pop(0) # O(n) each time!
# FAST: use collections.deque for FIFO queues
from collections import deque
queue = deque(range(10_000))
while queue:
item = queue.popleft() # O(1)

Arrays and lists both have O(1) access by index. The queue use case is about which end you remove from, not about list vs array.