Collections
2D Lists
Grids and Tables
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.
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.
Access a specific seat
Look up a value using row and column indices.
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.
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.
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.
Find a value's position
Search for a value and return its row/column.
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