array.tolist() converts a NumPy array into normal Python objects. A one-dimensional array becomes a list. A two-dimensional array becomes a nested list. A zero-dimensional array becomes a Python scalar.
This method is useful when data must leave NumPy and move into plain Python code, JSON output, web APIs, or test assertions. It is not the best choice when you still need fast vectorized NumPy operations, because lists do not keep NumPy’s array behavior.
Treat tolist() as a boundary tool. Keep arrays as arrays while computing, filtering, reshaping, or aggregating. Convert only when the next layer expects plain Python containers.
The official NumPy ndarray.tolist documentation explains how array items are converted to nearest compatible Python scalar objects. Related NumPy references include asarray, array, and NumPy data types. Related PythonPool guides cover NumPy reshape, NumPy ravel, NumPy flatten, NumPy arange, and NumPy first index.
Convert A 1D Array
For a one-dimensional array, tolist() returns a flat Python list.
import numpy as np
arr = np.array([10, 20, 30])
items = arr.tolist()
print(items)
print(type(items))
The result is a normal list, so list methods and plain Python loops work as expected.
This is often helpful for small results, configuration output, or code that must call a library that does not understand NumPy arrays.
Convert A 2D Array
For a two-dimensional array, tolist() preserves the row structure as nested lists.
import numpy as np
matrix = np.array([
[1, 2, 3],
[4, 5, 6],
])
rows = matrix.tolist()
print(rows)
print(rows[0])
This is useful when sending table-like data to an API or when comparing expected rows in tests.
The nesting follows the original array shape. A three-dimensional array would produce lists inside lists inside lists, which can become hard to inspect by hand.
Handle A Scalar Array
A zero-dimensional NumPy array becomes a Python scalar rather than a list.
import numpy as np
score = np.array(42)
plain_score = score.tolist()
print(plain_score)
print(type(plain_score))
This behavior is correct but easy to forget. If the caller always expects a list, handle scalar arrays before conversion.
For APIs, document whether a scalar result is allowed. Predictable output shape is more important than saving one line of conversion code.
Prepare JSON Output
The standard json module cannot serialize many NumPy objects directly. Convert arrays to lists first.
import json
import numpy as np
payload = {
"name": "samples",
"values": np.array([0.1, 0.2, 0.3]).tolist(),
}
text = json.dumps(payload)
print(text)
For nested arrays, the same method produces nested lists that JSON can encode.
For very large arrays, JSON output can become expensive and bulky. Consider summaries, pagination, binary formats, or files when the payload is large.
Recreate An Array With dtype
When converting back to NumPy, pass dtype if the exact type matters.
import numpy as np
arr = np.array([1, 2, 3], dtype=np.int16)
items = arr.tolist()
restored = np.array(items, dtype=np.int16)
print(restored)
print(restored.dtype)
The list does not remember the original NumPy dtype. Recreate that dtype deliberately when it matters for storage, memory, or downstream libraries.
This is especially important for small integer types, unsigned values, and precise floating-point formats. Plain Python objects do not carry the same dtype metadata.
Compare list() And tolist()
list(array) only converts the outer level. tolist() converts nested NumPy arrays too.
import numpy as np
matrix = np.array([[1, 2], [3, 4]])
outer_only = list(matrix)
fully_plain = matrix.tolist()
print(type(outer_only[0]))
print(type(fully_plain[0]))
For nested data, prefer tolist() when the goal is plain Python lists all the way down.
This distinction matters in tests. A shallow list conversion may still contain NumPy arrays, so equality checks can behave differently than expected.
Practical Guidance
Use tolist() at boundaries: JSON output, API payloads, snapshots, simple assertions, and places where code no longer needs NumPy operations. Keep arrays as arrays while doing numeric work.
Be aware that NumPy scalar types become close Python scalar types. That is usually helpful, but converting back may not preserve the exact dtype unless you request it.
For large arrays, conversion can allocate a lot of Python objects. If the next step can handle NumPy arrays, avoid conversion and pass the array directly.
The safest workflow is to convert only at the boundary, document whether nested lists are expected, and restore dtype explicitly when converting back to NumPy.
That keeps numeric code fast while still giving APIs and plain Python callers the format they expect.
When returning lists from a function, document the shape of the result. A flat list, nested row list, and scalar value are different contracts. Clear shape expectations make callers easier to test and reduce surprises when an array changes from one dimension to two.
This matters most at package and API boundaries.