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
相关产品推荐
相关产品推荐

