You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python收敛图绘制报错(列表索引需为整数/切片而非元组)的解决方法

问题解决:Jacobi/Gauss-Seidel迭代范数绘图报错处理

错误原因

报错'list indices must be integers or slices, not tuple'出现在第46、47行的res_jacobi[:,k]和res_gauss_seidel[:,k],因为res_jacobi是Python列表(结构为[分量1迭代列表, 分量2迭代列表, ...]),而非numpy数组,不支持二维数组的[:,k]索引语法。

修正后的完整代码

import numpy as np
import matplotlib.pyplot as plt

def jacobi(A, b, x0, tol=1e-10, max_iter=100):
    n = len(A)
    x = x0.copy()
    res = [[] for _ in range(n)]
    for k in range(max_iter):
        x_new = np.zeros_like(x)
        for i in range(n):
            s = 0
            for j in range(n):
                if i != j:
                    # 取标量值计算,避免维度不匹配
                    s += A[i][j] * x[j, 0]
            x_new[i, 0] = (b[i, 0] - s) / A[i][i]
            res[i].append(x_new[i, 0])
        if np.linalg.norm(x_new - x) < tol:
            return x_new, np.array(res).T  # 转置为(迭代步数, 分量数)的数组
        x = x_new.copy()
    return None, np.array(res).T

def gauss_seidel(A, b, x0, tol=1e-10, max_iter=100):
    n = len(A)
    x = x0.copy()
    res = [[] for _ in range(n)]
    for k in range(max_iter):
        x_old = x.copy()
        for i in range(n):
            s = 0
            for j in range(n):
                if i != j:
                    s += A[i][j] * x[j, 0]
            x[i, 0] = (b[i, 0] - s) / A[i][i]
            res[i].append(x[i, 0])
        # 统一收敛判断条件,和Jacobi保持一致
        if np.linalg.norm(x - x_old) < tol:
            return x, np.array(res).T
    return None, np.array(res).T

A = np.random.normal(0, 1, size=(4,4)) + 10000 * np.identity(4)
b = np.random.normal(0, 1, size=(4,1))
x_exact = np.linalg.solve(A, b)
x0_jacobi = np.random.normal(0, 1, size=(4,1))
x0_gauss_seidel = np.random.normal(0, 1, size=(4,1))

x_jacobi, res_jacobi = jacobi(A, b, x0_jacobi)
x_gauss_seidel, res_gauss_seidel = gauss_seidel(A, b, x0_gauss_seidel)

# 计算每一步的范数,res_jacobi现在是(迭代步数,4)的数组,转置后和x_exact匹配
jacobi_norms = [np.linalg.norm(x_exact - res_jacobi[k].reshape(4,1)) for k in range(len(res_jacobi))]
gauss_seidel_norms = [np.linalg.norm(x_exact - res_gauss_seidel[k].reshape(4,1)) for k in range(len(res_gauss_seidel))]

plt.plot(range(len(jacobi_norms)), jacobi_norms, label='Jacobi')
plt.plot(range(len(gauss_seidel_norms)), gauss_seidel_norms, label='Gauss-Seidel')
plt.xlabel('迭代步数k')
plt.ylabel('||x - xk||')
plt.legend()
plt.show()

关键修改说明

  1. 结果列表转numpy数组并转置:在两个迭代函数的返回语句中,将res转为numpy数组后执行.T转置,得到(迭代步数, 分量数)的结构,方便按步数提取完整迭代解。
  2. 维度匹配处理:
    • 迭代计算时,将列向量的元素取标量值(如x[j,0]),避免数组运算导致维度错误;
    • 计算范数时,将每一步的迭代解res_jacobi[k]reshape为列向量,和x_exact的维度对齐。
  3. 统一收敛判断条件:Gauss-Seidel函数中改用np.linalg.norm(x - x_old)判断收敛,和Jacobi逻辑保持一致,避免因残差计算方式不同导致的迭代次数差异。

内容的提问来源于stack exchange,提问作者CrustyCrab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:05:03