numpy
python
data-structures
lists
arrays

List of lists into numpy array

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Converting a Python list of lists into a NumPy array is done with np.array(). When all inner lists have the same length, the result is a regular 2D array. When they differ (ragged lists), NumPy creates an array of objects instead, which loses the performance benefits of a contiguous numeric array. Understanding this distinction is key to avoiding subtle bugs when converting nested Python data structures to NumPy.

Basic Conversion

python
1import numpy as np
2
3# Equal-length sublists → 2D array
4data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
5arr = np.array(data)
6
7print(arr)
8# [[1 2 3]
9#  [4 5 6]
10#  [7 8 9]]
11
12print(arr.shape)  # (3, 3)
13print(arr.dtype)  # int64

NumPy automatically infers the shape and dtype from the input data.

Specifying dtype

python
1# Force float type
2arr = np.array([[1, 2], [3, 4]], dtype=np.float32)
3print(arr.dtype)  # float32
4
5# Force specific integer type
6arr = np.array([[1, 2], [3, 4]], dtype=np.int8)
7print(arr.dtype)  # int8
8
9# Mixed int and float → all promoted to float
10arr = np.array([[1, 2.5], [3, 4]])
11print(arr.dtype)  # float64

Ragged (Uneven) Lists

When inner lists have different lengths, np.array() does not create a 2D numeric array:

python
1ragged = [[1, 2, 3], [4, 5], [6]]
2
3# NumPy 1.24+ raises a warning/error by default
4arr = np.array(ragged, dtype=object)
5print(arr)
6# [list([1, 2, 3]) list([4, 5]) list([6])]
7print(arr.shape)  # (3,) — 1D array of Python objects
8print(arr.dtype)  # object

To convert ragged lists to a regular array, pad the shorter lists:

python
1from itertools import zip_longest
2
3ragged = [[1, 2, 3], [4, 5], [6]]
4
5# Pad with zeros
6padded = list(zip_longest(*ragged, fillvalue=0))
7arr = np.array(padded).T
8print(arr)
9# [[1 2 3]
10#  [4 5 0]
11#  [6 0 0]]
12
13# Or use a helper function
14def pad_to_array(lists, fill=0):
15    max_len = max(len(row) for row in lists)
16    return np.array([row + [fill] * (max_len - len(row)) for row in lists])
17
18arr = pad_to_array(ragged)
19print(arr.shape)  # (3, 3)

3D and Higher Dimensions

Nested lists can create higher-dimensional arrays:

python
1# 3D: list of matrices
2data_3d = [
3    [[1, 2], [3, 4]],
4    [[5, 6], [7, 8]]
5]
6arr = np.array(data_3d)
7print(arr.shape)  # (2, 2, 2)
8
9# Access elements
10print(arr[0, 1, 0])  # 3 (first matrix, second row, first column)

Performance: np.array vs np.fromiter

python
1import time
2
3# List of lists — standard conversion
4data = [[i, i+1, i+2] for i in range(100000)]
5
6start = time.time()
7arr = np.array(data)
8print(f"np.array: {time.time() - start:.4f}s")
9
10# For flat data, np.fromiter is faster
11flat = [x for row in data for x in row]
12start = time.time()
13arr = np.fromiter(flat, dtype=int, count=len(flat)).reshape(-1, 3)
14print(f"np.fromiter: {time.time() - start:.4f}s")

For very large datasets, consider np.vstack, np.stack, or pre-allocating the array:

python
1# Pre-allocate and fill (fastest for known shapes)
2rows = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3arr = np.empty((len(rows), len(rows[0])), dtype=np.float64)
4for i, row in enumerate(rows):
5    arr[i] = row
6
7# np.vstack from a list of 1D arrays
8arrays = [np.array([1, 2, 3]), np.array([4, 5, 6])]
9arr = np.vstack(arrays)
10print(arr.shape)  # (2, 3)

Common Conversions

python
1# List of tuples
2data = [(1, 2), (3, 4), (5, 6)]
3arr = np.array(data)  # (3, 2) array
4
5# List of NumPy arrays
6arrays = [np.array([1, 2]), np.array([3, 4])]
7arr = np.stack(arrays)  # (2, 2) array
8
9# Pandas DataFrame to NumPy
10import pandas as pd
11df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
12arr = df.to_numpy()  # (2, 2) array

Common Pitfalls

  • Ragged lists silently create object arrays: Before NumPy 1.24, np.array([[1,2], [3]]) silently created a 1D array of list objects. In 1.24+, it raises VisibleDeprecationWarning. Always ensure inner lists have the same length for numeric arrays.
  • Mixed types causing dtype promotion: If one element is a string ([[1, 2], [3, "four"]]), the entire array becomes dtype object or <U21, losing numeric operations. Validate input data types before conversion.
  • Assuming np.array always makes a copy: np.array(existing_array) makes a copy by default, but np.asarray(existing_array) does not. Use np.asarray() when you want to avoid unnecessary copies.
  • Memory usage with large lists: Converting a 1-million-row list of lists to an array temporarily doubles memory (the list and the array both exist). For large data, read directly into NumPy with np.loadtxt, np.genfromtxt, or pandas.read_csv().to_numpy().
  • Column-major vs row-major ordering: np.array(data, order='C') creates row-major (C-contiguous) arrays (default). order='F' creates column-major (Fortran-contiguous). The wrong order can significantly slow operations that iterate along the non-contiguous axis.

Summary

  • Use np.array(list_of_lists) for direct conversion — works when all inner lists have equal length
  • Ragged (unequal-length) lists produce object arrays, not numeric arrays — pad or truncate first
  • Specify dtype explicitly to control the output type and avoid silent type promotion
  • For large data, use np.vstack, pre-allocated arrays, or np.fromiter for better performance
  • Use np.asarray() instead of np.array() to avoid unnecessary copies of existing arrays
  • Check .shape and .dtype after conversion to verify the result is what you expect

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.