HOWTO · Python
How to Create List of Lists in Python
This tutorial demonstrates how to create a list containing other lists in Python. Learn various methods including list comprehension, nested loops, and the append method. With clear examples and detailed explanations, you'll master this essential skill for organizing data efficiently.
On this page
A Python list can contain other lists as its elements. This structure is useful for keeping related sequences together, such as rows of values, groups of records, or nested data. A rectangular nested list of numbers can represent a matrix, but nested lists do not have to be rectangular: each inner list may have a different length.
The examples below show three ways to build this structure, followed by how to read and change its values. Choose the method that fits whether your inner lists already exist, you need a regular grid, or you are generating values step by step.
What a list of lists represents
An outer list stores references to its elements. When an element is itself a list, you can use the outer list to group those inner lists. For example, a classroom roster might be stored as one list per class, or a numeric grid as one list per row.
A nested list is not automatically a matrix. A matrix is a useful interpretation when rows have the same number of columns and the values represent a rectangular arrangement. Python permits rows with different lengths, which can be convenient for grouped data but requires care when iterating by column.
Create a list of lists from existing lists
If you already have inner lists, place them in an outer list literal. To add another existing list later, call the list method append() on the outer list. It adds its argument as one element at the end; it does not merge that list’s values into the outer list.
Run this example:
first = ["Ada", "Grace"]
second = ["Linus", "Guido"]
people_by_group = [first, second]
third = ["Barbara", "Margaret"]
people_by_group.append(third)
print(people_by_group)
The outer list contains three inner lists. Because the original lists are mutable objects, changing first later is visible through people_by_group[0] as well; both names refer to the same list.
Create independent rows with a nested list comprehension
For a fixed grid, a nested list comprehension creates each row separately. The outer comprehension runs once per row. Its expression is an inner comprehension that creates the values in that row.
Run this example:
rows, columns = 3, 4
grid = [[0 for _ in range(columns)] for _ in range(rows)]
print(grid)
Each pass of the outer comprehension evaluates a new inner list, so the rows can be changed independently. Use this pattern when you need a mutable grid initialized to the same value in every cell. Replace 0 with another starting value or expression as needed.
Build a list of lists with nested loops
Nested loops are useful when each value depends on its row or column, or when you want to make the construction steps explicit. Start with an outer list, create one row at a time, fill it in the inner loop, and then add the completed row.
Run this example:
rows, columns = 3, 4
grid = []
for row_index in range(rows):
row = []
for column_index in range(columns):
row.append(row_index * columns + column_index)
grid.append(row)
print(grid)
Here, each cell receives a value derived from its position. Calling append() on row adds one value; calling it on grid adds the completed row. This approach also works when the number or contents of the values are decided during iteration.
Access and update nested elements
Use one index for the outer list and another for the selected inner list: list_of_lists[row_index][column_index]. Python indexes from zero, so the first value in the first row is at [0][0]. Assign to the same expression to replace an element.
Run this example:
grid = [[2, 4, 6], [8, 10, 12]]
print(grid[1][0])
grid[0][2] = 7
print(grid)
The first index selects a row, and the second selects an item within it. The row index must identify an existing inner list, and the column index must exist in that selected row. If rows have different lengths, check the chosen row’s length before using a column index; a column available in one row may not exist in another.
Choose a construction method and avoid shared rows
Use a list literal when the sublists are already known. Use a nested list comprehension for a regular grid whose rows should be independent. Use nested loops when values are computed step by step or the construction needs additional logic. These approaches create new inner lists for each row.
A tempting shortcut for a grid is [[0] * columns] * rows. It repeats references to one inner list, rather than creating a separate list per row. As a result, changing a cell through one row also changes that position as seen through every row. For a mutable grid, use the nested comprehension shown above or build each row separately in a loop.
Nested lists can also have different row lengths when that matches the data. When processing such a structure, iterate through each row’s own values rather than assuming every row has the same number of columns. This keeps the construction and later access consistent with the shape of the data.