课程 13:列表的列表(多维列表)

学习目标

1. 多维列表基础概念

1.1 什么是多维列表?

多维列表是指列表中的元素还是列表,常用于表示矩阵、表格、图像像素等结构化数据。在Python中,我们主要使用二维列表(列表的列表),但理论上可以创建任意维度的列表。

重要概念:多维列表实际上是一维列表的嵌套,每一层嵌套增加一个维度。二维列表是最常用的多维列表形式。

1.2 二维列表的表示方法

二维列表可以形象地理解为表格或矩阵,其中第一个索引表示行,第二个索引表示列。

# 定义一个3x3的二维列表(矩阵)
matrix = [
    [1, 2, 3],    # 第0行
    [4, 5, 6],    # 第1行
    [7, 8, 9]     # 第2行
]

# 可视化表示:
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]

2. 二维列表的创建与初始化

2.1 直接定义法

# 方法1:直接定义
grid = [
    ['A', 'B', 'C'],
    ['D', 'E', 'F'],
    ['G', 'H', 'I']
]

# 方法2:逐行定义
board = []
board.append(['X', 'O', 'X'])
board.append(['O', 'X', 'O'])
board.append(['X', 'O', 'X'])

2.2 使用循环创建

# 创建5x5的空矩阵
rows, cols = 5, 5
matrix = []
for i in range(rows):
    row = []
    for j in range(cols):
        row.append(0)
    matrix.append(row)

# 使用列表推导式(更简洁)
matrix = [[0 for j in range(cols)] for i in range(rows)]

2.3 特殊矩阵的创建

# 单位矩阵(对角线为1,其余为0)
def create_identity_matrix(size):
    matrix = []
    for i in range(size):
        row = []
        for j in range(size):
            if i == j:
                row.append(1)
            else:
                row.append(0)
        matrix.append(row)
    return matrix

# 使用示例
identity_3x3 = create_identity_matrix(3)
print(identity_3x3)  # [[1, 0, 0], [0, 1, 0], [0, 0, 1]]

3. 访问和修改元素

3.1 基本访问操作

# 访问单个元素
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(matrix[0][0])  # 第0行第0列:1
print(matrix[1][2])  # 第1行第2列:6
print(matrix[2][1])  # 第2行第1列:8

# 访问整行
first_row = matrix[0]  # [1, 2, 3]
print(first_row)

3.2 边界检查和安全访问

# 安全的元素访问函数
def safe_get_element(matrix, row, col):
    """安全地获取矩阵元素,避免索引越界"""
    if (0 <= row < len(matrix) and 
        0 <= col < len(matrix[0])):
        return matrix[row][col]
    else:
        return None

# 使用示例
result = safe_get_element(matrix, 1, 2)  # 6
result = safe_get_element(matrix, 5, 0)  # None

3.3 修改元素

# 修改单个元素
matrix[1][1] = 99
print(matrix)  # [[1, 2, 3], [4, 99, 6], [7, 8, 9]]

# 批量修改
for i in range(len(matrix)):
    for j in range(len(matrix[0])):
        if matrix[i][j] % 2 == 0:  # 偶数
            matrix[i][j] *= 2       # 翻倍

4. 遍历多维列表

4.1 按行遍历

# 方法1:直接遍历行
for row in matrix:
    print(row)

# 方法2:使用索引遍历行
for i in range(len(matrix)):
    print(f"第{i}行: {matrix[i]}")

4.2 按元素遍历

# 方法1:嵌套循环
for row in matrix:
    for element in row:
        print(element, end=' ')
    print()  # 换行

# 方法2:使用索引
for i in range(len(matrix)):
    for j in range(len(matrix[0])):
        print(f"matrix[{i}][{j}] = {matrix[i][j]}")

4.3 按列遍历

# 按列遍历(需要知道列数)
cols = len(matrix[0])
for j in range(cols):
    column = []
    for i in range(len(matrix)):
        column.append(matrix[i][j])
    print(f"第{j}列: {column}")

4.4 对角线遍历

# 主对角线(左上到右下)
def get_main_diagonal(matrix):
    diagonal = []
    for i in range(len(matrix)):
        diagonal.append(matrix[i][i])
    return diagonal

# 副对角线(右上到左下)
def get_anti_diagonal(matrix):
    diagonal = []
    n = len(matrix)
    for i in range(n):
        diagonal.append(matrix[i][n-1-i])
    return diagonal

5. 常用操作和函数

5.1 获取矩阵信息

# 获取行数和列数
rows = len(matrix)
cols = len(matrix[0]) if matrix else 0

# 检查是否为方阵
def is_square(matrix):
    return len(matrix) == len(matrix[0]) if matrix else False

# 检查是否为空
def is_empty(matrix):
    return len(matrix) == 0 or len(matrix[0]) == 0

5.2 添加和删除操作

# 添加新行
new_row = [10, 11, 12]
matrix.append(new_row)

# 在指定位置插入行
matrix.insert(1, [13, 14, 15])

# 删除行
removed_row = matrix.pop()      # 删除最后一行
removed_row = matrix.pop(1)    # 删除索引为1的行

# 删除指定行
del matrix[0]

5.3 矩阵转置

# 矩阵转置(行变列,列变行)
def transpose(matrix):
    if not matrix:
        return []
    
    rows, cols = len(matrix), len(matrix[0])
    transposed = [[0 for _ in range(rows)] for _ in range(cols)]
    
    for i in range(rows):
        for j in range(cols):
            transposed[j][i] = matrix[i][j]
    
    return transposed

# 使用示例
original = [[1, 2, 3], [4, 5, 6]]
transposed = transpose(original)
print(transposed)  # [[1, 4], [2, 5], [3, 6]]

6. 列表推导式的应用

6.1 基础列表推导式

# 生成全0矩阵
zeros = [[0 for _ in range(3)] for _ in range(3)]

# 生成递增矩阵
increasing = [[i*3 + j + 1 for j in range(3)] for i in range(3)]

# 生成随机矩阵(需要random模块)
import random
random_matrix = [[random.randint(1, 10) for _ in range(3)] for _ in range(3)]

6.2 条件列表推导式

# 生成棋盘模式
def create_checkerboard(size):
    return [[1 if (i + j) % 2 == 0 else 0 
             for j in range(size)] 
            for i in range(size)]

# 生成螺旋矩阵
def create_spiral_matrix(n):
    matrix = [[0 for _ in range(n)] for _ in range(n)]
    # ... 螺旋填充逻辑
    return matrix

7. 实际应用场景

7.1 游戏开发

# 井字棋游戏板
def create_tictactoe_board():
    return [[' ' for _ in range(3)] for _ in range(3)]

def print_board(board):
    for row in board:
        print('|', end=' ')
        for cell in row:
            print(cell, end=' | ')
        print()
        print('-' * 13)

# 使用示例
board = create_tictactoe_board()
board[0][0] = 'X'
board[1][1] = 'O'
print_board(board)

7.2 图像处理

# 简单的图像表示(灰度图)
def create_image_matrix(width, height, default_value=0):
    """创建图像矩阵"""
    return [[default_value for _ in range(width)] for _ in range(height)]

def draw_rectangle(image, x1, y1, x2, y2, value):
    """在图像上绘制矩形"""
    for i in range(y1, y2 + 1):
        for j in range(x1, x2 + 1):
            if 0 <= i < len(image) and 0 <= j < len(image[0]):
                image[i][j] = value

# 使用示例
img = create_image_matrix(10, 10)
draw_rectangle(img, 2, 2, 7, 7, 255)  # 绘制白色矩形

7.3 数学计算

# 矩阵加法
def matrix_add(a, b):
    if len(a) != len(b) or len(a[0]) != len(b[0]):
        raise ValueError("矩阵维度不匹配")
    
    result = []
    for i in range(len(a)):
        row = []
        for j in range(len(a[0])):
            row.append(a[i][j] + b[i][j])
        result.append(row)
    return result

# 矩阵乘法
def matrix_multiply(a, b):
    if len(a[0]) != len(b):
        raise ValueError("矩阵维度不匹配")
    
    result = [[0 for _ in range(len(b[0]))] for _ in range(len(a))]
    
    for i in range(len(a)):
        for j in range(len(b[0])):
            for k in range(len(b)):
                result[i][j] += a[i][k] * b[k][j]
    
    return result

8. 高级概念与最佳实践

8.1 深拷贝与浅拷贝

# 浅拷贝问题
original = [[1, 2], [3, 4]]
shallow_copy = original.copy()  # 或 list(original)

# 修改嵌套列表会影响原列表
shallow_copy[0][0] = 99
print(original)      # [[99, 2], [3, 4]]
print(shallow_copy)  # [[99, 2], [3, 4]]

# 深拷贝解决方案
import copy
deep_copy = copy.deepcopy(original)
deep_copy[0][0] = 100
print(original)   # [[99, 2], [3, 4]]
print(deep_copy)  # [[100, 2], [3, 4]]

8.2 性能优化

# 预分配内存
def create_matrix_fast(rows, cols):
    matrix = [None] * rows
    for i in range(rows):
        matrix[i] = [0] * cols
    return matrix

# 使用NumPy(如果可用)
try:
    import numpy as np
    def create_matrix_numpy(rows, cols):
        return np.zeros((rows, cols))
except ImportError:
    print("NumPy不可用,使用标准方法")

8.3 错误处理

# 验证矩阵结构
def validate_matrix(matrix):
    """验证矩阵是否有效"""
    if not matrix:
        return False, "矩阵为空"
    
    if not isinstance(matrix[0], list):
        return False, "不是二维列表"
    
    first_row_length = len(matrix[0])
    for i, row in enumerate(matrix):
        if not isinstance(row, list):
            return False, f"第{i}行不是列表"
        if len(row) != first_row_length:
            return False, f"第{i}行长度不一致"
    
    return True, "矩阵有效"

# 使用示例
test_matrix = [[1, 2], [3, 4, 5]]
is_valid, message = validate_matrix(test_matrix)
print(f"验证结果: {message}")

9. 编程练习与挑战

练习1:基础操作

创建一个4x4的二维列表,元素为1~16,然后:

练习2:矩阵变换

实现以下矩阵操作:

练习3:游戏逻辑

实现一个简单的扫雷游戏:

10. 综合作业与项目

作业13:多维列表综合应用

任务1:矩阵计算器

创建一个矩阵计算器,支持以下功能:

任务2:图像处理程序

使用二维列表实现简单的图像处理:

任务3:游戏开发

选择以下游戏之一进行开发:

学习建议:多维列表是Python中处理结构化数据的重要工具。建议多动手实践,从简单的2x2矩阵开始,逐步扩展到更复杂的应用。记住,理解索引和嵌套循环是关键。
思考题:如何设计一个函数来检测二维列表中是否存在"鞍点"(即某行最大且某列最小的元素)?这个问题的解决思路是什么?