Editor

Python Program to Print a Matrix in Spiral Order

Intermediate · Matrices

Spiral order reads a matrix from the outside in: along the top row, down the right column, back along the bottom row, up the left column, and then round again on the inner part. This program keeps four boundaries, top, bottom, left and right, and moves them inwards after each side is read.

Program

spiral_matrix.py
matrix = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]]
print("Matrix:")
for row in matrix:
print(row)
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
spiral = []
while top <= bottom and left <= right:
for j in range(left, right + 1): # along the top row, left to right
spiral.append(matrix[top][j])
top += 1
for i in range(top, bottom + 1): # down the right column
spiral.append(matrix[i][right])
right -= 1
if top <= bottom:
for j in range(right, left - 1, -1): # along the bottom row, right to left
spiral.append(matrix[bottom][j])
bottom -= 1
if left <= right:
for i in range(bottom, top - 1, -1): # up the left column
spiral.append(matrix[i][left])
left += 1
print("Spiral order:", spiral)
Output
Matrix:
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
Spiral order: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]

How it works

  1. top, bottom, left and right mark the edges of the part of the matrix not read yet.
  2. Each pass of the while loop reads one ring: the top row, the right column, the bottom row backwards and the left column upwards.
  3. After a side is read, its boundary moves one step inwards, so it is never read twice.
  4. The two if checks stop a single leftover row or column from being read a second time, which matters for matrices that are not square, like this 3 x 4 one.
  5. The loop ends when the boundaries cross, which means every entry has been read.

Other ways to write it

Peeling off the top row and turning the rest

Peeling off the top row and turning the rest
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
grid = [row[:] for row in matrix] # work on a copy
spiral = []
while grid:
spiral += grid.pop(0) # take the top row
grid = [list(row) for row in zip(*grid)][::-1] # turn the rest anticlockwise
print("Spiral order:", spiral)
Output
Spiral order: [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]

Taking the top row and turning what is left a quarter turn anticlockwise brings the next side to the top each time. It is short, but it rebuilds the grid on every step.

Filling a matrix in spiral order

Filling a matrix in spiral order
n = 4
grid = [[0] * n for _ in range(n)]
moves = [(0, 1), (1, 0), (0, -1), (-1, 0)] # right, down, left, up
r = c = d = 0
for value in range(1, n * n + 1):
grid[r][c] = value
nr, nc = r + moves[d][0], c + moves[d][1]
if not (0 <= nr < n and 0 <= nc < n) or grid[nr][nc] != 0:
d = (d + 1) % 4 # hit an edge or a filled cell: turn right
nr, nc = r + moves[d][0], c + moves[d][1]
r, c = nr, nc
for row in grid:
print(" ".join(f"{v:2}" for v in row))
Output
 1  2  3  4
12 13 14  5
11 16 15  6
10  9  8  7

The reverse task writes 1 to n x n into the cells along the spiral, turning right whenever the next cell is off the grid or already filled.

Try it yourself

Add a fourth row, [13, 14, 15, 16], and predict the spiral order before you run it.

Edit the program above and press Run, or open it in the full editor to save it and share it. To watch it run line by line, open it in the visualizer.

All Python programs · CBSE class 12 practical file · Python exercises