How to Make a Matrix in Python (5 Easy Ways)

Say you’re tracking ticket sales for three movie theaters across four showtimes on a Friday. To make a matrix in Python, store that grid as a list of lists, one inner list per theater, or pass the same list to np.array() when you need math.

Both give you rows and columns you can index, loop over and total. The tricky part is building an empty grid without every row turning into the same list.

In this tutorial, I’ll show you how to make a matrix in Python five ways, plus user input, on one small ticket dataset. My test machine had Python 3.12.5 with NumPy 2.5.3, and every output below is pasted from those runs.

The ticket data we’ll use for every Python matrix

The running sample is the number of tickets three theaters sold at four showtimes on Friday, October 30, 2026. Each ticket costs $12.50.

Theater1 PM4 PM7 PM10 PM
Chicago486213571
Boston355812066
Phoenix52479840

So it’s a 3 x 4 matrix: 3 rows (theaters) and 4 columns (showtimes). A matrix is just a rectangular grid of numbers, and Python doesn’t have a built-in matrix type. That’s why a list of lists in Python is the usual starting point.

Method 1: Make a matrix with a nested list (Recommended for small data)

A nested list is a list whose items are lists. It needs no installs and it’s perfect for a small grid you read, print or edit by hand.

Here’s our ticket matrix as a nested list:

tickets = [
    [48, 62, 135, 71],    # Chicago
    [35, 58, 120, 66],    # Boston
    [52, 47, 98, 40],     # Phoenix
]

print(tickets[1][2])      # Boston, 7 PM show
print(len(tickets), "rows x", len(tickets[0]), "columns")

tickets[2][3] = 44        # fix Phoenix, 10 PM
for row in tickets:
    print(row)

Output:

120
3 rows x 4 columns
[48, 62, 135, 71]
[35, 58, 120, 66]
[52, 47, 98, 44]

Boston’s 7 PM show sold 120 tickets, the matrix is 3 rows by 4 columns, and Phoenix’s 10 PM count is now 44.

VS Code output of a Python nested list matrix showing one cell, the row and column count and each row
The nested list prints one cell, its size and each theater’s row after the Phoenix fix.

How does this code work?

tickets[1] picks the second row (Boston), and the next [2] picks the third column inside it (7 PM). Python counts from 0, so row 1 is the second row.

len(tickets) counts rows, and len(tickets[0]) counts the items in the first row, which is the column count. Assigning to tickets[2][3] changes one cell in place.

Important: nothing stops a nested list from having rows of different lengths. If one row has 3 numbers and the rest have 4, len(tickets[0]) lies about the width. NumPy checks this for you, which I’ll show in Method 3.

Method 2: Build a matrix with a list comprehension

When you need an empty grid to fill later, say a blank seat chart, a list comprehension in Python builds each row as a new list. It’s the safe way to make a matrix of zeros without NumPy.

Same 3 theaters by 4 showtimes, but empty. Here’s the code, with the common shortcut next to it:

rows, cols = 3, 4

grid = [[0] * cols for _ in range(rows)]
grid[0][2] = 135
print("good:", grid)

bad = [[0] * cols] * rows
bad[0][2] = 135
print("bad: ", bad)

print(grid[0] is grid[1], bad[0] is bad[1])

Output:

good: [[0, 0, 135, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
bad:  [[0, 0, 135, 0], [0, 0, 135, 0], [0, 0, 135, 0]]
False True

The good grid changes one cell. The bad grid shows 135 in the 7 PM column of all three rows, even though the code only set row 0.

VS Code output comparing a list comprehension matrix with the [[0]*4]*3 shortcut that repeats one change in every row
Setting one cell in the shortcut grid changes the same column in all three rows.

How does this code work?

[[0] * cols for _ in range(rows)] runs the inner [0] * cols three times, so you get three separate lists. Changing one leaves the others alone.

[[0] * cols] * rows builds one inner list and repeats a reference to it three times. That’s why bad[0] is bad[1] printed True: all three rows are one list in memory.

So here’s the catch: the bug is silent and only shows up when you write to a cell. The same reference idea is behind shallow vs deep copy in Python, and there’s more on grids in initializing a 2D array in Python.

Method 3: Make a matrix in Python with NumPy np.array()

Once you need totals, averages or matrix math, switch to NumPy. Install it with pip install numpy, then pass the same nested list to np.array().

Here’s the ticket matrix as a 2D NumPy array:

import numpy as np

tickets = np.array([[48, 62, 135, 71],
                    [35, 58, 120, 66],
                    [52, 47, 98, 40]])

print(tickets)
print(tickets.shape, tickets.ndim, tickets.dtype)
print(tickets[1, 2])         # Boston, 7 PM
print(tickets[:, 2])         # every theater at 7 PM
print(tickets.sum(axis=1))   # tickets per theater

Output:

[[ 48  62 135  71]
 [ 35  58 120  66]
 [ 52  47  98  40]]
(3, 4) 2 int64
120
[135 120  98]
[316 279 237]

The shape is (3, 4), the 7 PM column is 135, 120 and 98, and the theaters sold 316, 279 and 237 tickets.

VS Code output of a NumPy matrix made with np.array showing shape, a column slice and row totals
np.array() turns the nested list into a 3 by 4 int64 matrix with row totals in one call.

How does this code work?

np.array() copies the rows into one block of memory with a single data type, int64 here. .shape gives rows and columns, and .ndim is 2 for a matrix. My guide to the NumPy shape attribute goes deeper.

tickets[1, 2] uses one bracket with a comma. tickets[:, 2] means every row, column 2, which a nested list can’t do directly. sum(axis=1) adds across each row; there’s more on NumPy sum() by rows and columns.

Important: rows of different lengths now raise a ValueError about an inhomogeneous shape instead of building a broken matrix. More array basics are in the NumPy array tutorial.

Method 4: Create a matrix with np.zeros(), np.ones(), np.full() and np.eye()

When you know the size but not the values yet, NumPy’s filler functions make the matrix in one line. You pass the shape as a tuple: (rows, columns).

Here’s the code for a blank 3 x 4 ticket grid and a few others:

import numpy as np

print(np.zeros((3, 4), dtype=int))
print(np.ones((2, 3)))
print(np.full((3, 4), 12.50))
print(np.eye(3, dtype=int))

Output:

[[0 0 0 0]
 [0 0 0 0]
 [0 0 0 0]]
[[1. 1. 1.]
 [1. 1. 1.]]
[[12.5 12.5 12.5 12.5]
 [12.5 12.5 12.5 12.5]
 [12.5 12.5 12.5 12.5]]
[[1 0 0]
 [0 1 0]
 [0 0 1]]

You get a 3 x 4 grid of integer zeros, a 2 x 3 grid of float ones, a 3 x 4 grid of 12.5 (the ticket price) and a 3 x 3 identity matrix.

How does this code work?

np.zeros() and np.ones() default to floats, so pass dtype=int for whole numbers. np.full() fills every cell with the value you give it. There’s more on NumPy zeros().

np.eye(3) puts 1s on the diagonal and 0s everywhere else. If you want a truly empty placeholder or an empty list to append rows to, see creating an empty matrix in Python.

Pro Tip: np.full() keeps the data type of the fill value, so 12.50 gives floats and 0 gives integers. Pass dtype when you want something else.

Method 5: Reshape a range into a matrix with np.arange() and reshape()

Sometimes your data arrives as one flat list, for example 12 ticket counts read from a file. reshape() folds it into rows and columns without copying the numbers one by one.

Here’s the code, using seat numbers 1 to 12 and then our flat ticket list:

import numpy as np

seats = np.arange(1, 13).reshape(3, 4)
print(seats)

flat = [48, 62, 135, 71, 35, 58, 120, 66, 52, 47, 98, 40]
print(np.array(flat).reshape(3, -1)[2])

try:
    np.arange(10).reshape(3, 4)
except ValueError as err:
    print("ValueError:", err)

Output:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
[52 47 98 40]
ValueError: cannot reshape array of size 10 into shape (3,4)

Seats 1 to 12 become a 3 x 4 matrix, the flat list’s third row is Phoenix’s 52, 47, 98 and 40, and 10 numbers can’t fill 12 cells.

VS Code output of np.arange reshaped into a 3 by 4 matrix and a ValueError for a size that does not fit
reshape(3, 4) folds 12 numbers into a matrix, and 10 numbers raise a ValueError.

How does this code work?

np.arange(1, 13) makes 1 through 12, and .reshape(3, 4) fills them row by row. -1 tells NumPy to work out that size itself, so reshape(3, -1) also gives 4 columns.

The total cell count must match: 3 x 4 is 12, so arange(10) fails with cannot reshape array of size 10 into shape (3,4). There’s more in reshaping an array with NumPy.

How do you make a matrix from user input in Python?

Read the number of rows first, then one line of numbers per row. I ran this one in Command Prompt so I could type the ticket counts for real.

Here’s the code:

rows = int(input("How many theaters? "))

matrix = []
for i in range(rows):
    line = input(f"Tickets for theater {i + 1}: ")
    matrix.append([int(x) for x in line.split()])

print(matrix)
print("7 PM total:", sum(row[2] for row in matrix))

Output:

How many theaters? 3
Tickets for theater 1: 48 62 135 71
Tickets for theater 2: 35 58 120 66
Tickets for theater 3: 52 47 98 40
[[48, 62, 135, 71], [35, 58, 120, 66], [52, 47, 98, 40]]
7 PM total: 353

Typing the three theaters’ counts builds the same ticket matrix, and the 7 PM total comes out at 353 tickets.