You're building a seating chart for a theater. Each seat has a row and column. A nested list (list of lists) lets you store and access data by two coordinates - perfect for grids, game boards, and spreadsheets.

Create a seating chart

Initialize a 2D list to represent a grid of seats.

create_grid.py
def main():
    # Theater seating chart: rows x seats per row
    rows = 
    cols = 
    
    # Create 2D list using list comprehension
    seating = [[0 for col in range(cols)] for row in range(rows)]
    
    # Assign seat numbers (1, 2, 3, ...)
    seat_number = 1
    for row in range(rows):
        for col in range(cols):
            seating[row][col] = seat_number
            seat_number += 1
    
    # Display the seating chart
    print("=== Theater Seating Chart ===")
    for row_idx, row in enumerate(seating):
        print(f"Row {row_idx + 1}: ", end="")
        for seat in row:
            print(f"{seat}\t", end="")
        print()
    
    total_seats = rows * cols
    print(f"Total seats: {total_seats}")

main()
def main():
    # Theater seating chart: rows x seats per row
    rows = 
    cols = 
    
    # Create 2D list using list comprehension
    seating = [[0 for col in range(cols)] for row in range(rows)]
    
    # Assign seat numbers (1, 2, 3, ...)
    seat_number = 1
    for row in range(rows):
        for col in range(cols):
            seating[row][col] = seat_number
            seat_number += 1
    
    # Display the seating chart
    print("=== Theater Seating Chart ===")
    for row_idx, row in enumerate(seating):
        print(f"Row {row_idx + 1}: ", end="")
        for seat in row:
            print(f"{seat}\t", end="")
        print()
    
    total_seats = rows * cols
    print(f"Total seats: {total_seats}")

main()
def main():
    # Theater seating chart: rows x seats per row
    rows = 
    cols = 
    
    # Create 2D list using list comprehension
    seating = [[0 for col in range(cols)] for row in range(rows)]
    
    # Assign seat numbers (1, 2, 3, ...)
    seat_number = 1
    for row in range(rows):
        for col in range(cols):
            seating[row][col] = seat_number
            seat_number += 1
    
    # Display the seating chart
    print("=== Theater Seating Chart ===")
    for row_idx, row in enumerate(seating):
        print(f"Row {row_idx + 1}: ", end="")
        for seat in row:
            print(f"{seat}\t", end="")
        print()
    
    total_seats = rows * cols
    print(f"Total seats: {total_seats}")

main()
def main():
    # Theater seating chart: rows x seats per row
    rows = 
    cols = 
    
    # Create 2D list using list comprehension
    seating = [[0 for col in range(cols)] for row in range(rows)]
    
    # Assign seat numbers (1, 2, 3, ...)
    seat_number = 1
    for row in range(rows):
        for col in range(cols):
            seating[row][col] = seat_number
            seat_number += 1
    
    # Display the seating chart
    print("=== Theater Seating Chart ===")
    for row_idx, row in enumerate(seating):
        print(f"Row {row_idx + 1}: ", end="")
        for seat in row:
            print(f"{seat}\t", end="")
        print()
    
    total_seats = rows * cols
    print(f"Total seats: {total_seats}")

main()

A 2D list is a list of lists. Use list comprehension to create grids.

nested list List of lists: `grid = [[1,2], [3,4]]`. Access with `grid[row][col]`.

Access a specific seat

Look up a value using row and column indices.

access_element.py
def main():
    # Ticket prices by section (rows) and day (columns)
    # Rows: 0=Front, 1=Middle, 2=Back
    # Cols: 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri
    prices = [
        [50, 50, 55, 55, 75],   # Front row
        [40, 40, 45, 45, 60],   # Middle row  
        [25, 25, 30, 30, 45]    # Back row
    ]
    
    # Customer wants: middle section, Friday
    want_row = 
    want_col = 
    
    price = prices[want_row][want_col]
    
    sections = ["Front", "Middle", "Back"]
    days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
    
    print("=== Ticket Lookup ===")
    print(f"Section: {sections[want_row]}")
    print(f"Day: {days[want_col]}")
    print(f"Price: ${price}")
    
    # Show full price chart
    print("\n=== Full Price Chart ===")
    header = "        " + "\t".join(day[:3] for day in days)
    print(header)
    
    for r, row in enumerate(prices):
        row_str = "\t".join(f"${p}" for p in row)
        print(f"{sections[r]}\t{row_str}")

main()
def main():
    # Ticket prices by section (rows) and day (columns)
    # Rows: 0=Front, 1=Middle, 2=Back
    # Cols: 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri
    prices = [
        [50, 50, 55, 55, 75],   # Front row
        [40, 40, 45, 45, 60],   # Middle row  
        [25, 25, 30, 30, 45]    # Back row
    ]
    
    # Customer wants: middle section, Friday
    want_row = 
    want_col = 
    
    price = prices[want_row][want_col]
    
    sections = ["Front", "Middle", "Back"]
    days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
    
    print("=== Ticket Lookup ===")
    print(f"Section: {sections[want_row]}")
    print(f"Day: {days[want_col]}")
    print(f"Price: ${price}")
    
    # Show full price chart
    print("\n=== Full Price Chart ===")
    header = "        " + "\t".join(day[:3] for day in days)
    print(header)
    
    for r, row in enumerate(prices):
        row_str = "\t".join(f"${p}" for p in row)
        print(f"{sections[r]}\t{row_str}")

main()
def main():
    # Ticket prices by section (rows) and day (columns)
    # Rows: 0=Front, 1=Middle, 2=Back
    # Cols: 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri
    prices = [
        [50, 50, 55, 55, 75],   # Front row
        [40, 40, 45, 45, 60],   # Middle row  
        [25, 25, 30, 30, 45]    # Back row
    ]
    
    # Customer wants: middle section, Friday
    want_row = 
    want_col = 
    
    price = prices[want_row][want_col]
    
    sections = ["Front", "Middle", "Back"]
    days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
    
    print("=== Ticket Lookup ===")
    print(f"Section: {sections[want_row]}")
    print(f"Day: {days[want_col]}")
    print(f"Price: ${price}")
    
    # Show full price chart
    print("\n=== Full Price Chart ===")
    header = "        " + "\t".join(day[:3] for day in days)
    print(header)
    
    for r, row in enumerate(prices):
        row_str = "\t".join(f"${p}" for p in row)
        print(f"{sections[r]}\t{row_str}")

main()
def main():
    # Ticket prices by section (rows) and day (columns)
    # Rows: 0=Front, 1=Middle, 2=Back
    # Cols: 0=Mon, 1=Tue, 2=Wed, 3=Thu, 4=Fri
    prices = [
        [50, 50, 55, 55, 75],   # Front row
        [40, 40, 45, 45, 60],   # Middle row  
        [25, 25, 30, 30, 45]    # Back row
    ]
    
    # Customer wants: middle section, Friday
    want_row = 
    want_col = 
    
    price = prices[want_row][want_col]
    
    sections = ["Front", "Middle", "Back"]
    days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
    
    print("=== Ticket Lookup ===")
    print(f"Section: {sections[want_row]}")
    print(f"Day: {days[want_col]}")
    print(f"Price: ${price}")
    
    # Show full price chart
    print("\n=== Full Price Chart ===")
    header = "        " + "\t".join(day[:3] for day in days)
    print(header)
    
    for r, row in enumerate(prices):
        row_str = "\t".join(f"${p}" for p in row)
        print(f"{sections[r]}\t{row_str}")

main()

Access with two indices: grid[1][2] means row 1, column 2.

Mark a seat as reserved

Update a value at a specific position.

update_cell.py
def main():
    # Seating chart: 0 = available, 1 = reserved
    seats = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
    
    # Customer reservation (row, col)
    reserve_row = 
    reserve_col = 
    
    print("=== Before Reservation ===")
    print_seating(seats)
    
    # Make the reservation
    seats[reserve_row][reserve_col] = 1
    
    print(f"\n=== After Reserving Row {reserve_row + 1}, Seat {reserve_col + 1} ===")
    print_seating(seats)
    
    # Reserve more seats
    seats[0][0] = 1
    seats[2][3] = 1
    
    print("\n=== After Additional Reservations ===")
    print_seating(seats)
    
    # Count available seats using sum with generator
    available = sum(seat == 0 for row in seats for seat in row)
    print(f"\nAvailable seats: {available}")

def print_seating(seats):
    print("  1 2 3 4")
    for r, row in enumerate(seats):
        symbols = ["O" if s == 0 else "X" for s in row]
        print(f"{r + 1} {' '.join(symbols)}")

main()
def main():
    # Seating chart: 0 = available, 1 = reserved
    seats = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
    
    # Customer reservation (row, col)
    reserve_row = 
    reserve_col = 
    
    print("=== Before Reservation ===")
    print_seating(seats)
    
    # Make the reservation
    seats[reserve_row][reserve_col] = 1
    
    print(f"\n=== After Reserving Row {reserve_row + 1}, Seat {reserve_col + 1} ===")
    print_seating(seats)
    
    # Reserve more seats
    seats[0][0] = 1
    seats[2][3] = 1
    
    print("\n=== After Additional Reservations ===")
    print_seating(seats)
    
    # Count available seats using sum with generator
    available = sum(seat == 0 for row in seats for seat in row)
    print(f"\nAvailable seats: {available}")

def print_seating(seats):
    print("  1 2 3 4")
    for r, row in enumerate(seats):
        symbols = ["O" if s == 0 else "X" for s in row]
        print(f"{r + 1} {' '.join(symbols)}")

main()
def main():
    # Seating chart: 0 = available, 1 = reserved
    seats = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
    
    # Customer reservation (row, col)
    reserve_row = 
    reserve_col = 
    
    print("=== Before Reservation ===")
    print_seating(seats)
    
    # Make the reservation
    seats[reserve_row][reserve_col] = 1
    
    print(f"\n=== After Reserving Row {reserve_row + 1}, Seat {reserve_col + 1} ===")
    print_seating(seats)
    
    # Reserve more seats
    seats[0][0] = 1
    seats[2][3] = 1
    
    print("\n=== After Additional Reservations ===")
    print_seating(seats)
    
    # Count available seats using sum with generator
    available = sum(seat == 0 for row in seats for seat in row)
    print(f"\nAvailable seats: {available}")

def print_seating(seats):
    print("  1 2 3 4")
    for r, row in enumerate(seats):
        symbols = ["O" if s == 0 else "X" for s in row]
        print(f"{r + 1} {' '.join(symbols)}")

main()
def main():
    # Seating chart: 0 = available, 1 = reserved
    seats = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
    
    # Customer reservation (row, col)
    reserve_row = 
    reserve_col = 
    
    print("=== Before Reservation ===")
    print_seating(seats)
    
    # Make the reservation
    seats[reserve_row][reserve_col] = 1
    
    print(f"\n=== After Reserving Row {reserve_row + 1}, Seat {reserve_col + 1} ===")
    print_seating(seats)
    
    # Reserve more seats
    seats[0][0] = 1
    seats[2][3] = 1
    
    print("\n=== After Additional Reservations ===")
    print_seating(seats)
    
    # Count available seats using sum with generator
    available = sum(seat == 0 for row in seats for seat in row)
    print(f"\nAvailable seats: {available}")

def print_seating(seats):
    print("  1 2 3 4")
    for r, row in enumerate(seats):
        symbols = ["O" if s == 0 else "X" for s in row]
        print(f"{r + 1} {' '.join(symbols)}")

main()

Assign directly: grid[row][col] = value. Lists are mutable.

Sum all values

Calculate a total by traversing every cell.

sum_all.py
def main():
    # Monthly sales by product (in units)
    # Rows: Products (0=Widgets, 1=Gadgets, 2=Gizmos)
    # Cols: Months (0=Jan, 1=Feb, 2=Mar)
    sales = [
        [120, 135, 150],  # Widgets
        [80, 95, 110],    # Gadgets
        [200, 180, 220]   # Gizmos
    ]
    
    # Quarterly sales (4 products, 4 quarters)
    quarterly = [
        [1200, 1350, 1500, 1400],
        [800, 950, 1100, 1050],
        [2000, 1800, 2200, 2100],
        [500, 600, 700, 650]
    ]
    
    data = 
    
    # Calculate grand total - Pythonic way!
    grand_total = sum(sum(row) for row in data)
    
    print("=== Sales Summary ===")
    print(f"Grand Total: {grand_total} units")
    
    # Calculate row totals (per product)
    print("\n=== Per Product ===")
    products = ["Widgets", "Gadgets", "Gizmos", "Sprockets"]
    for i, row in enumerate(data):
        row_total = sum(row)
        print(f"{products[i]}: {row_total}")
    
    # Calculate column totals (per period)
    print("\n=== Per Period ===")
    num_periods = len(data[0])
    for col in range(num_periods):
        col_total = sum(row[col] for row in data)
        print(f"Period {col + 1}: {col_total}")

main()
def main():
    # Monthly sales by product (in units)
    # Rows: Products (0=Widgets, 1=Gadgets, 2=Gizmos)
    # Cols: Months (0=Jan, 1=Feb, 2=Mar)
    sales = [
        [120, 135, 150],  # Widgets
        [80, 95, 110],    # Gadgets
        [200, 180, 220]   # Gizmos
    ]
    
    # Quarterly sales (4 products, 4 quarters)
    quarterly = [
        [1200, 1350, 1500, 1400],
        [800, 950, 1100, 1050],
        [2000, 1800, 2200, 2100],
        [500, 600, 700, 650]
    ]
    
    data = 
    
    # Calculate grand total - Pythonic way!
    grand_total = sum(sum(row) for row in data)
    
    print("=== Sales Summary ===")
    print(f"Grand Total: {grand_total} units")
    
    # Calculate row totals (per product)
    print("\n=== Per Product ===")
    products = ["Widgets", "Gadgets", "Gizmos", "Sprockets"]
    for i, row in enumerate(data):
        row_total = sum(row)
        print(f"{products[i]}: {row_total}")
    
    # Calculate column totals (per period)
    print("\n=== Per Period ===")
    num_periods = len(data[0])
    for col in range(num_periods):
        col_total = sum(row[col] for row in data)
        print(f"Period {col + 1}: {col_total}")

main()

Use nested loops or nested comprehensions to visit every cell.

row-major Process row by row: `for row in grid: for val in row:`

Find a value's position

Search for a value and return its row/column.

find_position.py
def main():
    # Movie theater seat map with seat IDs
    seat_map = [
        ["A1", "A2", "A3", "A4", "A5"],
        ["B1", "B2", "B3", "B4", "B5"],
        ["C1", "C2", "C3", "C4", "C5"],
        ["D1", "D2", "D3", "D4", "D5"]
    ]
    
    # Find this seat
    target_seat = 
    
    # Search for the seat
    found_row = -1
    found_col = -1
    
    for row_idx, row in enumerate(seat_map):
        if target_seat in row:
            found_row = row_idx
            found_col = row.index(target_seat)
            break
    
    print("=== Seat Finder ===")
    print(f"Looking for seat: {target_seat}")
    
    if found_row != -1:
        print("Found at position:")
        print(f"  Row index: {found_row} (Row {found_row + 1})")
        print(f"  Col index: {found_col} (Seat {found_col + 1})")
        
        print(f"\nDirections: Walk to row {found_row + 1}, " +
              f"then count {found_col + 1} seat(s) from the left.")
    else:
        print("Seat not found!")
    
    # Show the map with target highlighted
    print("\n=== Seat Map ===")
    for row_idx, row in enumerate(seat_map):
        for col_idx, seat in enumerate(row):
            if row_idx == found_row and col_idx == found_col:
                print(f"[{seat}]", end="\t")
            else:
                print(f" {seat} ", end="\t")
        print()

main()
def main():
    # Movie theater seat map with seat IDs
    seat_map = [
        ["A1", "A2", "A3", "A4", "A5"],
        ["B1", "B2", "B3", "B4", "B5"],
        ["C1", "C2", "C3", "C4", "C5"],
        ["D1", "D2", "D3", "D4", "D5"]
    ]
    
    # Find this seat
    target_seat = 
    
    # Search for the seat
    found_row = -1
    found_col = -1
    
    for row_idx, row in enumerate(seat_map):
        if target_seat in row:
            found_row = row_idx
            found_col = row.index(target_seat)
            break
    
    print("=== Seat Finder ===")
    print(f"Looking for seat: {target_seat}")
    
    if found_row != -1:
        print("Found at position:")
        print(f"  Row index: {found_row} (Row {found_row + 1})")
        print(f"  Col index: {found_col} (Seat {found_col + 1})")
        
        print(f"\nDirections: Walk to row {found_row + 1}, " +
              f"then count {found_col + 1} seat(s) from the left.")
    else:
        print("Seat not found!")
    
    # Show the map with target highlighted
    print("\n=== Seat Map ===")
    for row_idx, row in enumerate(seat_map):
        for col_idx, seat in enumerate(row):
            if row_idx == found_row and col_idx == found_col:
                print(f"[{seat}]", end="\t")
            else:
                print(f" {seat} ", end="\t")
        print()

main()

Return early when found. Return None or (-1, -1) if not found.

Exercise: comprehension.py

Create 2D lists with list comprehensions