# One list that holds other lists.
# nested lists — structure, access, iteration, modification

# ─────────────────────────────────────────────
# Creating a nested list
# ─────────────────────────────────────────────

squads = [
    ["Raven", "Wolf", "Ghost"],
    ["Viper", "Bull", "Fox"],
    ["Hawk", "Stone", "Cruz"]
]

print(squads)
# [['Raven', 'Wolf', 'Ghost'], ['Viper', 'Bull', 'Fox'], ['Hawk', 'Stone', 'Cruz']]

print(len(squads))      # 3  — number of inner lists, not total elements

# ─────────────────────────────────────────────
# Accessing elements — outer index, then inner
# ─────────────────────────────────────────────

print(squads[0])        # ['Raven', 'Wolf', 'Ghost']
print(squads[1])        # ['Viper', 'Bull', 'Fox']
print(squads[2])        # ['Hawk', 'Stone', 'Cruz']

print(squads[0][0])     # Raven  — first element of first list
print(squads[0][1])     # Wolf   — second element of first list
print(squads[1][2])     # Fox    — third element of second list
print(squads[2][-1])    # Cruz   — last element of third list

# ─────────────────────────────────────────────
# Looping — outer loop, then inner loop
# ─────────────────────────────────────────────

for squad in squads:
    for member in squad:
        print(member)

# Raven / Wolf / Ghost / Viper / Bull / Fox / Hawk / Stone / Cruz

# with enumerate — track squad number
for i, squad in enumerate(squads, 1):
    print(f"Squad {i}: {squad}")

# Squad 1: ['Raven', 'Wolf', 'Ghost']
# Squad 2: ['Viper', 'Bull', 'Fox']
# Squad 3: ['Hawk', 'Stone', 'Cruz']

# with both indexes visible
for i, squad in enumerate(squads):
    for j, member in enumerate(squad):
        print(f"squads[{i}][{j}] = {member}")

# squads[0][0] = Raven
# squads[0][1] = Wolf
# ...

# ─────────────────────────────────────────────
# Grid — rows and columns
# ─────────────────────────────────────────────

grid = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(grid[0][0])   # 1  — row 0, column 0
print(grid[1][2])   # 6  — row 1, column 2
print(grid[2][1])   # 8  — row 2, column 1

# print the full grid row by row
for row in grid:
    print(row)

# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]

# ─────────────────────────────────────────────
# Modifying inner lists
# ─────────────────────────────────────────────

squads = [
    ["Raven", "Wolf", "Ghost"],
    ["Viper", "Bull", "Fox"]
]

squads[0].append("Cruz")
print(squads[0])    # ['Raven', 'Wolf', 'Ghost', 'Cruz']

squads[1].remove("Fox")
print(squads[1])    # ['Viper', 'Bull']

squads[0][1] = "Blade"          # update a specific element
print(squads[0])    # ['Raven', 'Blade', 'Ghost', 'Cruz']

# ─────────────────────────────────────────────
# Inner lists can have different lengths
# ─────────────────────────────────────────────

mixed = [
    ["Raven"],
    ["Wolf", "Ghost", "Viper"],
    ["Bull", "Fox"]
]

for squad in mixed:
    print(f"{len(squad)} members: {squad}")

# 1 members: ['Raven']
# 3 members: ['Wolf', 'Ghost', 'Viper']
# 2 members: ['Bull', 'Fox']

# ─────────────────────────────────────────────
# Quick reference
# ─────────────────────────────────────────────

# nested = [[...], [...], [...]]   — list of lists
# nested[i]                        — inner list at index i
# nested[i][j]                     — element j inside inner list i
# len(nested)                      — number of inner lists
# len(nested[i])                   — length of one inner list
#
# for inner in nested:             — iterate over inner lists
#     for item in inner:           — iterate over elements
#
# all list methods work on inner lists
# inner lists can have different lengths
