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

Python实现Bellman-Ford最短路径调用addEdge报TypeError如何修复

报错原因

TypeError: list indices must be integers or slices, not str

这个报错的核心原因是你当前使用的Bellman-Ford实现默认节点用整数索引访问,但你传入了字符串类型的代币名称作为节点标识,执行dist[src]时尝试用字符串下标访问列表就会触发报错。

修复方案

你需要新增代币名称和整数索引的双向映射,同时适配原Graph类的输出逻辑,满足用代币名作为节点标识的需求,另外你的原测试逻辑还有多处可优化的错误点,完整修复代码如下:

from collections import defaultdict
import numpy as np
import pandas as pd # 原代码用到了df1,需提前导入pandas

stableCoins = ['USDT', 'USDC', 'DAI']
# 此处需确保你已提前定义好distinct_pairnames和汇率矩阵df1
# distinct_pairnames = ['USDT', 'USDC', 'DAI', 'BTC', 'ETH'] 示例
# df1 = pd.DataFrame(...) 你的实际汇率数据

class Graph:
    def __init__(self, vertices, idx_to_token):
        self.V = vertices # 顶点数量
        self.graph = []
        self.idx_to_token = idx_to_token # 传入索引转代币名的映射
    # 给图添加边
    def addEdge(self, u, v, w):
        self.graph.append([u, v, w])
    # 打印结果适配代币名称
    def printArr(self, dist):
        print("Vertex Distance from Source ")
        for i in range(self.V):
            print(f"{self.idx_to_token[i]} -> {dist[i]}")
    # Bellman-Ford算法主函数,可检测负权回路
    def bellmanFord(self, src):
        # 初始化所有节点到源点的距离为无穷大
        dist = [float("Inf")] * self.V
        dist[src] = 0
        # 对所有边松弛|V|-1次
        for i in range(self.V - 1):
            for u, v, w in self.graph:
                if dist[u] != float("Inf") and dist[u] + w < dist[v]:
                    dist[v] = dist[u] + w
        # 检测负权回路
        for u, v, w in self.graph:
            if dist[u] != float("Inf") and dist[u] + w < dist[v]:
                print("Negative Cycles !")
                return
        self.printArr(dist)

# 测试运行
if __name__ == "__main__":
    # 1. 先建立代币名和整数索引的双向映射
    token_to_idx = {token: idx for idx, token in enumerate(distinct_pairnames)}
    idx_to_token = {idx: token for token, idx in token_to_idx.items()}
    vertex_count = len(distinct_pairnames)
    # 2. 全局初始化一次图即可,不需要每次循环新建
    g = Graph(vertex_count, idx_to_token)
    
    # 3. 遍历所有代币对添加边
    for u_token in distinct_pairnames:
        for v_token in distinct_pairnames:
            if u_token == v_token:
                continue
            # 跳过无效汇率
            if pd.isna(df1.loc[u_token, v_token]) or df1.loc[u_token, v_token] == 1:
                continue
            u_idx = token_to_idx[u_token]
            v_idx = token_to_idx[v_token]
            weight = -np.log(float(df1.loc[u_token, v_token]))
            g.addEdge(u_idx, v_idx, weight)
    
    # 4. 以每个稳定币为源点跑Bellman-Ford
    for stable_token in stableCoins:
        print(f"\n=== 源点为{stable_token}的最短路径 ===")
        src_idx = token_to_idx[stable_token]
        g.bellmanFord(src_idx)
关键修改点说明
  • 新增了token_to_idx和idx_to_token两个映射字典,实现代币名称和整数索引的互相转换,解决字符串下标报错的问题
  • 优化了图初始化逻辑:原代码每次三层循环都新建图,效率极低且逻辑错误,现在全局只初始化一次图,提前把所有有效边加进去
  • 修复了原判断逻辑的语法错误:原代码(多个bool值) != 1的写法不符合Python语法规范,现在单独判断每个汇率是否有效
  • 适配了输出逻辑:打印结果会直接输出代币名称而非整数索引,符合你的使用需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:54:04