Python NumPy: How to Flatten a List of NumPy Arrays in Python
When working with numerical data in Python, you'll often encounter situations where data is stored as a list of separate NumPy arrays, for example, outputs from batch processing, model predictions, or chunked data reads. Flattening this structure into a single one-dimensional array simplifies downstream operations like plotting, statistical analysis, or saving to a file.
For example:
- Input:
[np.array([[1, 2]]), np.array([[3, 4]]), np.array([[5, 6]])] - Output:
[1, 2, 3, 4, 5, 6]
This guide covers multiple approaches using NumPy's built-in functions, explains the differences between them, and helps you choose the right one for your use case.
Using np.concatenate() with .ravel() (Recommended)
The most robust and commonly used approach is np.concatenate(), which joins a sequence of arrays along an existing axis. Combined with .ravel(), it produces a flat one-dimensional array.
import numpy as np
list_of_arrays = [
np.array([[1, 2]]),
np.array([[3, 4]]),
np.array([[5, 6]]),
np.array([[7, 8]])
]
flat = np.concatenate(list_of_arrays).ravel()
print(flat)
Output:
[1 2 3 4 5 6 7 8]
How It Works
np.concatenate(list_of_arrays)joins all arrays along the first axis (axis=0), producing a single 2D array..ravel()flattens that 2D array into a 1D array.
np.concatenate() works reliably even when the arrays in your list have different shapes (as long as they're compatible along the concatenation axis). The other methods that first convert to a single array with np.array() require all sub-arrays to have identical shapes.
Handling Arrays with Different Shapes
This is where np.concatenate() truly shines compared to other methods:
import numpy as np
# Arrays with different numbers of elements
list_of_arrays = [
np.array([1, 2, 3]),
np.array([4, 5]),
np.array([6, 7, 8, 9])
]
flat = np.concatenate(list_of_arrays)
print(flat)
Output:
[1 2 3 4 5 6 7 8 9]
If you try np.array(list_of_arrays).flatten() with arrays of different lengths, NumPy will either raise an error or create an array of objects instead of numbers:
import numpy as np
list_of_arrays = [
np.array([1, 2, 3]),
np.array([4, 5]), # Different length!
np.array([6, 7, 8, 9]) # Different length!
]
# This creates an object array, NOT a numeric array
result = np.array(list_of_arrays, dtype=object).flatten()
print(result)
Output:
[array([1, 2, 3]) array([4, 5]) array([6, 7, 8, 9])]
NOT what we want!
Always use np.concatenate() when your arrays may have different shapes.
Using .flatten()
The .flatten() method returns a new copy of the array collapsed into one dimension. This approach works when all arrays in the list have the same shape.
import numpy as np
list_of_arrays = [
np.array([[1, 2]]),
np.array([[3, 4]]),
np.array([[5, 6]]),
np.array([[7, 8]])
]
flat = np.array(list_of_arrays).flatten()
print(flat)
Output:
[1 2 3 4 5 6 7 8]
The key characteristic of .flatten() is that it always returns a copy of the data. Any modifications to the flattened array won't affect the original.
Using .ravel()
The .ravel() method also returns a 1D array, but unlike .flatten(), it returns a view of the original data when possible rather than a copy. This makes it more memory-efficient.
import numpy as np
list_of_arrays = [
np.array([[1, 2]]),
np.array([[3, 4]]),
np.array([[5, 6]]),
np.array([[7, 8]])
]
flat = np.array(list_of_arrays).ravel()
print(flat)
Output:
[1 2 3 4 5 6 7 8]
flatten() vs ravel() - When does it matter?| Feature | .flatten() | .ravel() |
|---|---|---|
| Returns | Always a copy | A view when possible |
| Memory | Uses more memory | More memory-efficient |
| Modifying result affects original? | No | Potentially yes |
Use .flatten() when you need an independent copy. Use .ravel() when you want to save memory and don't plan to modify the result.
Using .reshape(-1)
The .reshape(-1) method reshapes the array into a 1D array, where -1 tells NumPy to automatically calculate the required length. Like .ravel(), it returns a view when possible.
import numpy as np
list_of_arrays = [
np.array([[1, 2]]),
np.array([[3, 4]]),
np.array([[5, 6]]),
np.array([[7, 8]])
]
flat = np.array(list_of_arrays).reshape(-1)
print(flat)
Output:
[1 2 3 4 5 6 7 8]
The -1 parameter is a convenient shorthand meaning "whatever size is needed to fit all elements into a single dimension."
Using np.hstack()
np.hstack() stacks arrays horizontally (column-wise). For 1D arrays, it effectively concatenates them into a single flat array:
import numpy as np
list_of_arrays = [
np.array([1, 2, 3]),
np.array([4, 5]),
np.array([6, 7, 8, 9])
]
flat = np.hstack(list_of_arrays)
print(flat)
Output:
[1 2 3 4 5 6 7 8 9]
Like np.concatenate(), np.hstack() handles arrays of different lengths without issues.
Converting the Result to a Python List
All the methods above return a NumPy array. If you need a standard Python list instead, simply call .tolist():
import numpy as np
list_of_arrays = [
np.array([[1, 2]]),
np.array([[3, 4]]),
np.array([[5, 6]])
]
flat_list = np.concatenate(list_of_arrays).ravel().tolist()
print(flat_list)
print(type(flat_list))
Output:
[1, 2, 3, 4, 5, 6]
<class 'list'>
Comparison of Approaches
| Method | Handles Different Shapes | Returns Copy or View | Memory Efficiency |
|---|---|---|---|
np.concatenate().ravel() | ✅ | View (when possible) | ⭐⭐⭐⭐⭐ |
np.hstack() | ✅ | Depends | ⭐⭐⭐⭐ |
np.array().flatten() | ❌ (same shape only) | Always copy | ⭐⭐⭐ |
np.array().ravel() | ❌ (same shape only) | View (when possible) | ⭐⭐⭐⭐ |
np.array().reshape(-1) | ❌ (same shape only) | View (when possible) | ⭐⭐⭐⭐ |
Conclusion
For most real-world scenarios, np.concatenate() combined with .ravel() is the best choice: it's reliable, efficient, and handles arrays of different shapes gracefully.
If all your arrays share the same shape, .flatten(), .ravel(), and .reshape(-1) all work well, with .ravel() being the most memory-efficient of the three. Use .flatten() when you specifically need an independent copy of the data, and prefer .ravel() or .reshape(-1) when memory efficiency matters.