Nested Lists


Explanation: A Python nested list is a list that contains other lists as its elements. This allows you to represent complex, hierarchical data structures, such as matrices (tables), grids, or trees. Each inner list acts as a row or a sub-collection within the main list. Understanding Python lists of lists is crucial for working with multi-dimensional data.

Note: python list of lists, python matrix, multi-dimensional list python, access nested list python, python nested data structures.

Code Examples:

# Example 1 (Beginner-Friendly): Basic nested list (representing a 2x2 grid)
# A simple list where each element is itself a list.
grid = [[1, 2], [3, 4]]
print(f"Basic grid: {grid}")
print(f"Type of grid: {type(grid)}")
print(f"Type of first element (a list): {type(grid[0])}")

# Example 2 (Slightly More Complex): Accessing elements in a nested list
# Accessing an element requires multiple indices: [row_index][column_index].
matrix = [[10, 20, 30],
          [40, 50, 60],
          [70, 80, 90]]
print(f"\nMatrix: {matrix}")
print(f"Element at row 0, column 1: {matrix[0][1]}") # Output: 20
print(f"Element at row 2, column 0: {matrix[2][0]}") # Output: 70

# Example 3 (Intermediate): Iterating through a nested list
# Using nested loops to process each element.
print("\nIterating through matrix elements:")
for row in matrix:
    for element in row:
        print(element, end=" ") # Print elements of a row on same line
    print() # Newline after each row

# Example 4 (Advanced Beginner): Modifying elements in a nested list
# Since lists are mutable, you can change individual elements within nested lists.
game_board = [["X", "O", " "],
              [" ", "X", " "],
              ["O", " ", "X"]]
print(f"\nInitial game board: {game_board}")
game_board[0][2] = "O" # Change top-right empty space to 'O'
game_board[1][0] = "O" # Change middle-left empty space to 'O'
print(f"Modified game board: {game_board}")

# Example 5 (Intermediate): Adding rows/columns to a nested list
# Using append() or other methods to change the structure.
student_records = [
    ["Alice", 90, 85],
    ["Bob", 75, 92]
]
print(f"\nStudent records: {student_records}")
student_records.append(["Charlie", 88, 79]) # Add a new student record (new row)
print(f"After adding Charlie: {student_records}")

# Adding a new score for all students (simulating a new column)
# This is more complex and usually involves a loop or list comprehension
new_quiz_scores = [95, 80, 82] # Scores for Alice, Bob, Charlie respectively
for i, record in enumerate(student_records):
    record.append(new_quiz_scores[i])
print(f"After adding quiz scores: {student_records}")

# Example 6 (Advanced): Using list comprehensions to create nested lists dynamically
# Creating a chess board representation (8x8 with alternating colors)
chessboard = [["B" if (r + c) % 2 == 0 else "W" for c in range(8)] for r in range(8)]
print("\nChessboard (B=Black, W=White):")
for row in chessboard:
    print(" ".join(row))

# Example 7 (Advanced): Deep copy vs. Shallow copy with nested lists
# Assigning nested lists can lead to unexpected behavior if not careful.
# A shallow copy only copies references to inner lists, not the inner lists themselves.
# A deep copy creates entirely new copies of all nested structures.
original_data = [[1, 2], [3, 4]]
shallow_copy = list(original_data) # Creates a shallow copy
import copy
deep_copy = copy.deepcopy(original_data) # Creates a deep copy

print(f"\nOriginal: {original_data}")
print(f"Shallow Copy: {shallow_copy}")
print(f"Deep Copy: {deep_copy}")

# Modify an element in the inner list of the original
original_data[0][0] = 99

print(f"\nAfter modifying original[0][0] to 99:")
print(f"Original: {original_data}")      # Output: [[99, 2], [3, 4]]
print(f"Shallow Copy: {shallow_copy}") # Output: [[99, 2], [3, 4]] (changed because it refers to the same inner list)
print(f"Deep Copy: {deep_copy}")       # Output: [[1, 2], [3, 4]] (unchanged because it's a new independent copy)