For a regular Python grid, use a nested list comprehension so every row is created independently: grid = [[0 for _ in range(cols)] for _ in range(rows)]. For numerical work, initialize a NumPy array with a shape tuple, such as np.zeros((rows, cols), dtype=int). Choose nested lists for flexible Python containers and NumPy when you need its rectangular, uniform-type array behavior.
Initialize a 2D structure with a Python list
Python has no built-in two-dimensional list type, but a list of lists works well for many grids and tables. Set the number of rows and columns, then create each row separately:
rows, cols = 3, 4
grid = [[0 for _ in range(cols)] for _ in range(rows)]
This creates a 3-by-4 grid of zeros. The outer comprehension runs once per row, and the inner comprehension builds that row’s columns.
Avoid repeating one row object
Do not use grid = [[0] * cols] * rows when rows need to be independent. The outer list multiplication repeats references to the same inner list, so changing a cell in one row can change the corresponding cell in every row. The nested comprehension avoids that by creating a fresh row each time.
#1 Best Overall
Initialize a NumPy 2D array
NumPy is a good fit when you want a rectangular multidimensional array with a uniform element type, especially for numerical operations. Pass the shape as (rows, columns). NumPy’s documentation also shows creating a 2D array from a list of lists. NumPy array creation and its beginner guide explain these approaches.
import numpy as np
rows, cols = 3, 4
zeros = np.zeros((rows, cols), dtype=int)
ones = np.ones((rows, cols), dtype=int)
filled = np.full((rows, cols), 7, dtype=int)
Use np.zeros or np.ones for those specific starting values, and np.full when every cell should begin with another value. NumPy’s zeros function defaults to float64; pass a dtype such as int when you want integer values. See the NumPy zeros reference.
Rank #2
Choose an initializer
| Starting contents | NumPy pattern | What to know |
|---|---|---|
| Zeros | np.zeros((rows, cols), dtype=int) |
Without a dtype argument, zeros defaults to float64. |
| Ones | np.ones((rows, cols), dtype=int) |
Pass the shape as a tuple. |
| One repeated value | np.full((rows, cols), value) |
Replace value with the desired fill value. |
| Contents will all be overwritten | np.empty((rows, cols)) |
Values are uninitialized. Assign every element before reading the array. |
NumPy describes empty as useful when speed matters and every element will be filled afterward. It does not initialize cells to zeros, so do not rely on the values before writing them. NumPy’s beginner guide covers this distinction.
Convert existing nested data
To turn rows of existing values into an ndarray, pass a list of lists to np.array:
Free tools Windows power users keep installed
One-click scans. No signup required.
data = [[1, 2], [3, 4]]
array = np.array(data)
For a regular 2D array, each row must have the same number of columns. NumPy arrays are rectangular and use a uniform element type; a jagged set of rows does not fit the regular 2D-array model described in the NumPy beginner guide.
Quick Recap
Best Value
Choose nested lists or NumPy
- Use a nested list for a simple grid or when ordinary Python containers are the desired structure.
- Use a NumPy ndarray for numerical work that benefits from a rectangular shape and uniform element type.
- Use
np.array(data)to convert existing, equally sized rows when they should become an ndarray.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




