Six flat values placed into a 2×3 grid using row-major index math. The trace 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

Pre-initialise a 2×3 grid of zeros. For each flat index i, compute the target row r = i // cols and column c = i % cols, then write flat[i] into grid[r][c]. The grid shows the fill progressing across the first row before moving to the second.

naive.py
Replay: real traced execution (multi-file project)
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)
  1. flat ← [1, 2, 3, 4, 5, 6]

    1flat = [1, 2, 3, 4, 5, 6]2rows, cols = 2, 3
    values this step[1, 2, 3, 4, 5, 6]flat
  2. cols ← 3, rows ← 2

    1flat = [1, 2, 3, 4, 5, 6]2rows, cols = 2, 33grid = [[0, 0, 0], [0, 0, 0]]
    values this step3cols2rows
  3. grid ← [[0, 0, 0], [0, 0, 0]]

    2rows, cols = 2, 33grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):
    values this step[[0, 0, 0], [0, 0, 0]]grid
  4. i ← 0

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
    values this step0i
  5. r ← 0

    4for i in range(rows * cols):5    r = i // cols6    c = i % cols
    values this step0r
  6. c ← 0

    5r = i // cols6c = i % cols7grid[r][c] = flat[i]
    values this step0c
  7. grid ← [[1, 0, 0], [0, 0, 0]]

    6    c = i % cols7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this step[[0, 0, 0], [0, 0, 0]] [[1, 0, 0], [0, 0, 0]]grid
  8. i ← 1

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
    values this step0 1i
  9. r = i // cols

    4for i in range(rows * cols):5    r = i // cols6    c = i % cols
  10. c ← 1

    5r = i // cols6c = i % cols7grid[r][c] = flat[i]
    values this step0 1c
  11. grid ← [[1, 2, 0], [0, 0, 0]]

    6    c = i % cols7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this step[[1, 0, 0], [0, 0, 0]] [[1, 2, 0], [0, 0, 0]]grid
  12. i ← 2

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
    values this step1 2i
  13. r = i // cols

    4for i in range(rows * cols):5    r = i // cols6    c = i % cols
  14. c ← 2

    5r = i // cols6c = i % cols7grid[r][c] = flat[i]
    values this step1 2c
  15. grid ← [[1, 2, 3], [0, 0, 0]]

    6    c = i % cols7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this step[[1, 2, 0], [0, 0, 0]] [[1, 2, 3], [0, 0, 0]]grid
  16. i ← 3

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
    values this step2 3i
  17. r ← 1

    4for i in range(rows * cols):5    r = i // cols6    c = i % cols
    values this step0 1r
  18. c ← 0

    5r = i // cols6c = i % cols7grid[r][c] = flat[i]
    values this step2 0c
  19. grid ← [[1, 2, 3], [4, 0, 0]]

    6    c = i % cols7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this step[[1, 2, 3], [0, 0, 0]] [[1, 2, 3], [4, 0, 0]]grid
  20. i ← 4

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
    values this step3 4i
  21. r = i // cols

    4for i in range(rows * cols):5    r = i // cols6    c = i % cols
  22. c ← 1

    5r = i // cols6c = i % cols7grid[r][c] = flat[i]
    values this step0 1c
  23. grid ← [[1, 2, 3], [4, 5, 0]]

    6    c = i % cols7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this step[[1, 2, 3], [4, 0, 0]] [[1, 2, 3], [4, 5, 0]]grid
  24. i ← 5

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
    values this step4 5i
  25. r = i // cols

    4for i in range(rows * cols):5    r = i // cols6    c = i % cols
  26. c ← 2

    5r = i // cols6c = i % cols7grid[r][c] = flat[i]
    values this step1 2c
  27. grid ← [[1, 2, 3], [4, 5, 6]]

    6    c = i % cols7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this step[[1, 2, 3], [4, 5, 0]] [[1, 2, 3], [4, 5, 6]]grid
  28. for i in range(rows * cols):

    3grid = [[0, 0, 0], [0, 0, 0]]4for i in range(rows * cols):5    r = i // cols
  29. stdout ← RESULT: [[1, 2, 3], [4, 5, 6]]

    7    grid[r][c] = flat[i]8print('RESULT:', grid)
    values this stepRESULT: [[1, 2, 3], [4, 5, 6]]stdout

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.

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.