Working with Text and Collections

Nested Lists: Lists Within Lists

4 min read

When one level of data isn't enough

A list of names is flat: ["Ram", "Preethi", "Sathish"]. But real data is often more structured. Think of an employee record system that tracks an ID list, a name list, and an age list together — or a spreadsheet, which is really a grid of rows and columns.

Python lists can hold any type of item, including other lists. A nested list — a list of lists — is how Python represents multi-level data like tables, grids, and grouped records.


Creating a nested list

employee_list = [
    [1, 2, 3, 4],
    ["Ram", "Preethi", "Sathish", "John"]
]

Here employee_list has two top-level components: a list of IDs and a list of names. Each of those, in turn, has its own sub-level components.


Accessing components with double brackets

To reach a top-level component, use one pair of square brackets — just like a normal list:

employee_list = [
    [1, 2, 3, 4],
    ["Ram", "Preethi", "Sathish", "John"]
]

print(employee_list[0])   # [1, 2, 3, 4]
print(employee_list[1])   # ['Ram', 'Preethi', 'Sathish', 'John']

To reach an item inside one of those inner lists, add a second pair of square brackets:

print(employee_list[1][1])   # Preethi
print(employee_list[0][2])   # 3

Reading it aloud: "Go to top-level component 1 (the names list), then get sub-level item 1 (the second name)." The first index picks which inner list; the second index picks the item inside it.


Modifying components by index

You can update a nested value the same way you'd update a flat list — just with two indexes:

employee_list = [
    [1, 2, 3, 4],
    ["Ram", "Preethi", "Sathish", "John"]
]

employee_list[0][3] = 5              # change 4 to 5 in the id list
employee_list[1][3] = "Karan"        # replace "John" with "Karan"

print(employee_list)
# [[1, 2, 3, 5], ['Ram', 'Preethi', 'Sathish', 'Karan']]

Modifying nested lists with methods

The same list methods you already know — .append(), .insert(), del, .remove(), .pop() — work on nested lists too. You just target the inner list first with an index, then call the method on it.

.append() — add to a sub-level list

employee_list[0].append(5)              # add id 5
employee_list[1].append("Nirmal")       # add name "Nirmal"
print(employee_list)
# [[1, 2, 3, 4, 5], ['Ram', 'Preethi', 'Sathish', 'John', 'Nirmal']]

You can also append an entirely new list — this adds a whole new top-level component:

age_list = [24, 27, 30, 22]
employee_list.append(age_list)
print(employee_list)
# [[1, 2, 3, 4], ['Ram', 'Preethi', 'Sathish', 'John'], [24, 27, 30, 22]]

.insert() — add at a specific position

employee_list[0].insert(1, 6)   # insert id 6 at position 1
print(employee_list[0])
# [1, 6, 2, 3, 4]

del — remove by index

del employee_list[2]     # drop the whole age_list (top-level component 2)
print(employee_list)
# [[1, 6, 2, 3, 4], ['Ram', 'Preethi', 'Sathish', 'John']]

.remove() — remove by value

employee_list[1].remove("Ram")   # removes the first "Ram" found
print(employee_list[1])
# ['Preethi', 'Sathish', 'John']

.pop() — remove and return by index

removed = employee_list[0].pop(4)   # remove the item at position 4 of the id list
print("Removed:", removed)
print(employee_list[0])

A practical example: building an N×M grid

Nested lists are the standard way to represent a grid or matrix in plain Python. Here's a pattern that builds an N×M grid of sequential numbers using nested for loops (you'll cover loops in detail soon, but this previews how naturally they pair with nested lists):

rows = 3
cols = 3
grid = []
count = 0

for r in range(rows):
    row = []
    for c in range(cols):
        row.append(count)
        count += 1
    grid.append(row)

print(grid)
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

The outer loop builds each row; the inner loop fills that row with values before it gets appended to grid. This is exactly how you'd build a tic-tac-toe board, a seating chart, or a spreadsheet-style table in Python.


Key takeaway

A nested list is a list whose items are themselves lists — the go-to structure for tables, grids, and grouped records. Access an item with two indexes, outer[i][j]: the first picks the inner list, the second picks the item inside it. Every list method you already know — .append(), .insert(), del, .remove(), .pop() — works the same way once you've indexed into the right sub-list.

What's next?

Nested lists are still mutable at every level — anything inside them can change. Sometimes you want the opposite: a small, fixed group of values that should never be modified. Python's tuple is built for exactly that.