# GESP等级：三级 | GESP Python 三级考点

"""
第5节：二维列表（嵌套列表）
知识点文件
GESP #38

【记忆钩子】
  二维列表 = 表格有行有列  →  matrix[行][列]

【核心概念】
  列表里的元素还可以是列表 —— 这就构成了二维列表（也称嵌套列表）。
  它就像一张 Excel 表格，有"行"和"列"两个维度。
  数学上对应"矩阵"概念。
"""

# ============================================================
# ① 创建二维列表
# ============================================================

# 方式一：直接字面量（最常用）
matrix = [
    [1, 2, 3],   # 第0行
    [4, 5, 6],   # 第1行
    [7, 8, 9]    # 第2行
]
# matrix 就是一个 3×3 的二维列表（3行3列）

# 方式二：空二维列表 + 追加
empty_matrix = []                     # 先创建一个空列表
row1 = [10, 20]
row2 = [30, 40]
empty_matrix.append(row1)            # 把行列表追加进去
empty_matrix.append(row2)
# empty_matrix → [[10, 20], [30, 40]]

# 方式三：列表推导式创建（进阶）
rows, cols = 3, 4
grid = [[0] * cols for _ in range(rows)]
# grid → [[0, 0, 0, 0],
#         [0, 0, 0, 0],
#         [0, 0, 0, 0]]

print("=" * 40)
print("【演示1】创建二维列表")
print("matrix =", matrix)
print("empty_matrix =", empty_matrix)
print("grid 3×4 全零矩阵 =", grid)


# ============================================================
# ② 二维列表的索引 —— matrix[行][列]
# ============================================================

# 先取"行"，再取"列"
# matrix[行索引][列索引]

print("\n" + "=" * 40)
print("【演示2】二维列表的索引")

# 取第0行第0列 → 1
val_00 = matrix[0][0]
print(f"matrix[0][0] = {val_00}    # 第0行第0列")

# 取第1行第2列 → 6
val_12 = matrix[1][2]
print(f"matrix[1][2] = {val_12}    # 第1行第2列")

# 取第2行第1列 → 8
val_21 = matrix[2][1]
print(f"matrix[2][1] = {val_21}    # 第2行第1列")

# 取整行
row_1 = matrix[1]
print(f"matrix[1] 整行 = {row_1}  # 第1行的完整列表")

# 负索引同样适用
print(f"matrix[-1][-1] = {matrix[-1][-1]}  # 最后一行最后一列")

# 修改元素
matrix[0][1] = 99
print(f"修改后 matrix = {matrix}")
# 注意：改回原值，保持示例整洁
matrix[0][1] = 2


# ============================================================
# ③ 遍历二维列表
# ============================================================

print("\n" + "=" * 40)
print("【演示3】遍历二维列表")

# 方式一：for row in matrix —— 逐行遍历
print("方式一：for row in matrix 逐行遍历")
for row in matrix:
    print("  ", row)

# 方式二：双重 for —— 逐个访问每个元素
print("\n方式二：双重 for 访问每个元素")
for row in matrix:
    for item in row:
        print(f"  {item}", end=" ")
    print()  # 换行

# 方式三：带索引遍历
print("\n方式三：带索引遍历")
for i in range(len(matrix)):          # i = 行索引
    for j in range(len(matrix[i])):   # j = 列索引
        print(f"matrix[{i}][{j}]={matrix[i][j]}", end="  ")
    print()

# 方式四：enumerate + 双重索引
print("\n方式四：使用 enumerate")
for i, row in enumerate(matrix):
    for j, value in enumerate(row):
        print(f"({i},{j}):{value}", end=" ")
    print()


# ============================================================
# ④ 常用操作
# ============================================================

print("\n" + "=" * 40)
print("【演示4】常用操作")

# 行数（外层列表长度）
rows_count = len(matrix)
print(f"行数 = len(matrix) = {rows_count}")

# 列数（任意一行的长度，前提是规则矩阵）
cols_count = len(matrix[0])
print(f"列数 = len(matrix[0]) = {cols_count}")

# 判断是否为规则矩阵
def is_regular_matrix(mat):
    """检查二维列表是否是规则的（每行列数相同）"""
    if not mat:
        return True
    first_len = len(mat[0])
    for row in mat:
        if len(row) != first_len:
            return False
    return True

print(f"matrix 是规则矩阵吗？{is_regular_matrix(matrix)}")

# 不规则二维列表（每行长度可以不同）
jagged = [
    [1, 2],
    [3, 4, 5, 6],
    [7]
]
print(f"jagged（锯齿数组）: {jagged}")
print(f"jagged 是规则矩阵吗？{is_regular_matrix(jagged)}")

print("\n" + "=" * 40)
print("知识点总结")
print("  • 创建: matrix = [[a,b],[c,d]]")
print("  • 索引: matrix[行][列]")
print("  • 遍历: for row in matrix + for item in row")
print("  • 行数: len(matrix)  列数: len(matrix[0])")
print("  • 记忆: 二维列表 = 表格, 先取行再取列")
print("=" * 40)
