Skip to main content
MahiDev — Learn. Build. Become AI-ready.

Lesson 05

Nested Lists, 2D Lists, and Matrices

Work with inner lists, multi-level indexing and slicing, matrix rows, nested loops, combining 2D lists, and shallow copy pitfalls.

Intermediate25 min

What you will learn

Nested Lists · 2D Lists · Matrices

A nested list is simply a list inside another list. It is the foundation for tables, seating charts, spreadsheets, game boards, and matrices.

Concept Meaning
Nested list List element that is itself a list
Matrix List of rows, each row a list
matrix[i][j] Row i, column j

Memory formula: Row → Column → Cell

After File 04 — sort, copy, and del, you can organize rows safely — this lesson shows how to structure and traverse 2D data.

Learning roadmap

Nested list index loop matrix roadmap

1. What is a nested list?

A nested list contains another list as an element.

Visual structure

Outer list with inner list at index 2
python
lst = [10, "RS", [1, 2, 3], 45.67]

print(lst[2])      # Inner list
print(lst[2][1])   # Second value inside inner list

Output:

text
[1, 2, 3]
2

Think of it like this:

  • lst[2] → entire inner list
  • lst[2][1] → one value inside that list

2. Multi-level indexing

A matrix uses two indexes: row first, then column.

3x3 matrix with matrix[1][2] highlighted
python
matrix = [
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
]

print(matrix[1][2])  # 60

Formula

matrix[row][column]

Expression Meaning
matrix[0] First row
matrix[1] Second row
matrix[1][2] Row 1, column 2

3. Updating inner lists

Each row is a normal Python list — use list methods on matrix[row_index].

Before append to row 0
python
data = [["A", "B"], ["X", "Y"]]

data[0].append("C")
print(data)  # [['A', 'B', 'C'], ['X', 'Y']]

You can also modify values directly:

python
data[1][0] = "Z"
print(data)  # [['A', 'B', 'C'], ['Z', 'Y']]

4. Slicing inside nested lists

Slicing works at each level.

row[0][1:3] selects columns 1 and 2
python
row = [
    [1, 2, 3, 4],
    [5, 6, 7, 8]
]

print(row[0][1:3])  # [2, 3]

Rule: First choose the row, then slice the columns.

5. Iterating through rows

Simple row loop

python
matrix = [
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
]

for row in matrix:
    print(row)

Output:

text
[10, 20, 30]
[40, 50, 60]
[70, 80, 90]
Each iteration prints one row

Each iteration gives one entire row.

6. Access every cell (nested loop)

python
for i, row in enumerate(matrix):
    for j, value in enumerate(row):
        print(f"({i},{j}) = {value}")

Visual traversal

Nested loop visits every cell row by row

Output begins like this:

text
(0,0) = 10
(0,1) = 20
(0,2) = 30
...

This pattern is used in spreadsheets, games, and image processing.

7. Combining two matrices

The + operator joins rows, not numbers.

Matrix A plus Matrix B concatenates rows
python
m1 = [[10, 20], [30, 40]]
m2 = [[1, 2], [3, 4]]

combined = m1 + m2
print(combined)

Output:

text
[[10, 20], [30, 40], [1, 2], [3, 4]]

It does not produce [[11, 22], ...]. That requires mathematical addition (loops or NumPy).

8. Shallow copy warning (most important)

This is one of the most common interview questions.

python
a = [[1, 2], [3, 4]]

b = a.copy()

b[0].append(99)

print(a)  # [[1, 2, 99], [3, 4]]
print(b)  # [[1, 2, 99], [3, 4]]

Why?

Shallow copy — outer copied, inner lists shared

copy() duplicates the outer list only. Inner list objects are still shared. See Aliasing and Copying for the full picture.

Safe deep copy

python
import copy

a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)

Now both inner lists become independent.

Mini project — classroom seating chart

Imagine a classroom arranged in rows.

python
seating = [
    ["A1", "A2", "A3"],
    ["B1", "B2", "B3"]
]

for row in range(len(seating)):
    for col in range(len(seating[row])):
        print(f"Row {row}, Col {col}: {seating[row][col]}")

Visual classroom

Classroom seating grid with row and column labels

Output:

text
Row 0, Col 0: A1
Row 0, Col 1: A2
Row 0, Col 2: A3
Row 1, Col 0: B1
...

One-page revision sheet

Task Syntax
Access row matrix[i]
Access cell matrix[i][j]
Update value matrix[i][j] = x
Add to row matrix[i].append(x)
Slice columns matrix[i][1:3]
Loop rows for row in matrix
Loop every cell Nested for loop
Combine matrices m1 + m2

Common interview mistakes

Mistake 1 — expecting + to add numbers:

python
m1 + m2  # joins rows only — not [[11, 22], ...]

Correct: + concatenates the outer list.

Mistake 2 — assuming copy() is deep:

python
b = a.copy()  # inner lists still shared

Correct: Use copy.deepcopy() when inner lists must also be independent.

Practice questions

Test yourself before File 06 — Tuple Deep Dive:

  1. How do you access the value 90 from a 3×3 matrix?
  2. What is the difference between matrix[1] and matrix[1][0]?
  3. Why does matrix.copy() still share inner lists?
  4. How do you print every cell with row and column numbers?
  5. What does m1 + m2 actually combine?

Knowledge check

Q1: How do you access 90 in a 3×3 matrix ending with [70, 80, 90]?
Answer: matrix[2][2] — row 2, column 2.

Q2: matrix[1] vs matrix[1][0]?
Answer: matrix[1] is the entire second row; matrix[1][0] is the first cell in that row.

Q3: Why does matrix.copy() share inner lists?
Answer: copy() is shallow — only the outer list is duplicated; inner list objects are reused.

Q4: Print every cell with row and column numbers?
Answer: Nested loop with enumerate, or for row in range(len(matrix)): with inner for col in range(len(matrix[row])):.

Q5: What does m1 + m2 combine?
Answer: The outer lists — all rows from m1 followed by all rows from m2.

Loading playground…