numpy
python
file-io
data-storage
serialization

How to save a list of numpy arrays into a single file and load file back to original form

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you need to save several NumPy arrays into one file and load them back later, the usual answer is an .npz archive. NumPy provides this directly through np.savez and np.savez_compressed, which preserve each array as a separate .npy entry inside a single container file.

Why .npz Is the Right Default

NumPy's savez format is designed for exactly this case: multiple arrays in one file. When you later call np.load, you get an NpzFile, which behaves like a dictionary of arrays.

This is better than trying to force a Python list of differently shaped arrays into one regular ndarray, because arrays with different shapes do not combine naturally into a single numeric block.

In practice:

  • use .npy for one array
  • use .npz for multiple arrays

Saving a List with Positional Arguments

If order matters and names do not, pass the arrays positionally:

python
1import numpy as np
2
3arrays = [
4    np.arange(5),
5    np.arange(6).reshape(2, 3),
6    np.array([[10.5, 11.5], [12.5, 13.5]]),
7]
8
9np.savez("arrays.npz", *arrays)

NumPy stores those arrays under generated names such as arr_0, arr_1, and arr_2.

To load them back into a Python list in the same order:

python
1import numpy as np
2
3with np.load("arrays.npz") as data:
4    arrays = [data[key] for key in data.files]
5
6for arr in arrays:
7    print(arr.shape)

data.files preserves the stored key order, so reconstructing the list is straightforward.

Saving with Explicit Names

If the arrays have meaning beyond list position, named entries are clearer:

python
1import numpy as np
2
3weights = np.random.rand(3, 3)
4bias = np.random.rand(3)
5labels = np.array([1, 0, 1, 1])
6
7np.savez("model_parts.npz", weights=weights, bias=bias, labels=labels)

Loading is then self-documenting:

python
1import numpy as np
2
3with np.load("model_parts.npz") as data:
4    weights = data["weights"]
5    bias = data["bias"]
6    labels = data["labels"]

This is often better than rebuilding a list by index because the meaning of each array is visible in the file keys.

Compressed Archives

If disk size matters more than a little extra CPU time, use np.savez_compressed:

python
import numpy as np

np.savez_compressed("arrays_compressed.npz", *arrays)

The loading code is the same. Compression is especially useful for large arrays with repeated values or sparse-like patterns, though the exact benefit depends on the data.

Preserving the Original "List of Arrays" Shape

People often ask to "load the file back to original form." That usually means:

  • still a Python list
  • each element still a NumPy array
  • each array keeps its original shape and dtype

np.savez handles that well as long as each stored entry is a normal array. Rebuilding the list after loading is one line:

python
with np.load("arrays.npz") as data:
    original_form = [data[key] for key in data.files]

That is the important distinction. The file itself stores named arrays, not a Python list object. You recreate the list at load time.

What About pickle

You can serialize a list of arrays directly with pickle, but that should not be the first choice for plain numeric arrays.

python
1import pickle
2
3with open("arrays.pkl", "wb") as f:
4    pickle.dump(arrays, f)

This works, but NumPy's own binary formats are generally better for array storage because they are clearer, more interoperable in NumPy workflows, and avoid pickling unless you actually need Python-object semantics.

There is also a security angle: loading pickled data from untrusted sources is unsafe.

Avoid Object Arrays Unless You Really Need Them

Another pattern you may see is:

python
np.save("arrays.npy", np.array(arrays, dtype=object))

This creates an object array, which relies on pickling when saved and loaded. It can work, but it is usually less explicit and less desirable than a normal .npz archive.

If your goal is simply "multiple arrays in one file," .npz is the cleaner solution.

Common Pitfalls

One common mistake is trying to call np.save on a list of arrays with different shapes and expecting a normal numeric array to appear. NumPy cannot stack incompatible shapes automatically.

Another issue is forgetting that np.load("file.npz") returns an archive-like object, not a Python list. You still need to extract the arrays and rebuild the list yourself.

Developers also sometimes use positional savez arguments and later forget which generated key corresponds to which array. If the arrays have semantic roles, name them explicitly.

Finally, be careful with pickled object arrays. They are less portable and less safe than plain NumPy array storage.

Summary

  • Use np.savez or np.savez_compressed to store multiple NumPy arrays in one file.
  • Load the archive with np.load and rebuild a list with data.files.
  • Use named keys when the arrays have semantic meaning.
  • Prefer .npz over pickling for ordinary numeric array collections.
  • Avoid object-array serialization unless you truly need Python-object behavior.

Course illustration
Course illustration

All Rights Reserved.