Six flat values placed into a 2×3 grid using row-major index math. The replay shows r and c computed from each flat index i via i // cols and i % cols, and grid filling left-to-right, top-to-bottom.

By hand

With NumPy

np.array(flat).reshape(2, 3) creates a 1-D array and reinterprets its memory as 2 rows of 3 columns without copying. The snapshot shows the array's shape, element type, and values as a nested Python list.

naive.py
flat = [1, 2, 3, 4, 5, 6]
rows, cols = 2, 3
grid = [[0, 0, 0], [0, 0, 0]]
for i in range(rows * cols):
    r = i // cols
    c = i % cols
    grid[r][c] = flat[i]
print('RESULT:', grid)
library.py
import numpy as np

flat = [1, 2, 3, 4, 5, 6]
arr = np.array(flat).reshape(2, 3)
print('shape:', arr.shape)
print('dtype:', arr.dtype)
print('values:', arr.tolist())
print('RESULT:', arr.tolist())
shape: (2, 3)
dtype: int64
values: [[1, 2, 3], [4, 5, 6]]
RESULT: [[1, 2, 3], [4, 5, 6]]

Implementation notes

  • NumPy uses row-major (C) order by default: elements are stored in memory left-to-right within each row, then row by row. The index formulas r = i // cols and c = i % cols implement exactly this layout.
  • reshape returns a view of the original data whenever possible — no copy is made. Modifying the reshaped array also modifies the original. Pass .reshape(...).copy() to force an independent copy.
  • One dimension may be given as -1 and NumPy infers it: np.arange(6).reshape(2, -1) gives the same 2×3 result.
  • This operation is the column-parallel inverse of zip-columns-to-rows in python-data-basics/ch08: where that lesson assembles separate column lists into row tuples, reshape takes a flat sequence and partitions it into rows.
  • Shape, dtype, and values are shown explicitly here because ndarray.__repr__ output varies with NumPy version and print options.