Python向多维列表追加浮点数触发IndexError索引越界报错
执行列表append操作触发IndexError: list index out of range
问题表现
向列表pChange追加浮点数temp时触发IndexError: list index out of range(列表索引超出范围)报错,异常仅出现在pChange[j].append(temp)语句执行环节,其余代码可正常运行。
复现代码如下:
import pandas as pd def loadPrices(fn): #从prices.txt读取价格数据 global nt, nInst df = pd.read_csv(fn, sep='\s+', header=None, index_col=None) nt, nInst = df.values.shape return (df.values).T pricesFile = "./prices.txt" prcAll = loadPrices(pricesFile) #数据存储在prcAll中 pChange = [[]]*20 j = 0 print(pChange[j]) for stock in prcAll: for i in range(1,5,1): temp = prcAll[j][i] / prcAll[j][i-1] pChange[j].append(temp) j = j+1
根因分析
代码存在两处问题,直接触发索引越界的是第一点:
- 硬编码
pChange初始化长度为20,但实际从文件读入的股票总数nInst(即转置后prcAll的第一维长度)大于20。变量j随外层循环每次自增1,当j的值达到20时,pChange只有索引0到19对应的元素,访问pChange[j]直接触发索引越界。 - 列表初始化写法
pChange = [[]]*20存在逻辑缺陷:该写法生成的20个元素指向同一个空列表对象的引用,并非20个独立的空列表。就算股票总数刚好为20不触发越界,所有append操作都会修改同一个底层列表,最终pChange里的20个子列表内容完全相同,不符合分股票存储涨跌幅的预期。
修复方案
- 初始化
pChange时不要硬编码长度,以实际读入的股票数量nInst为准,同时用列表推导式生成独立子列表,避免引用复用问题。 - 外层遍历
prcAll时直接用enumerate获取当前索引,不需要手动维护计数变量j,从根源避免计数和实际遍历长度不匹配的问题。
修复后可正常运行的代码:
import pandas as pd def loadPrices(fn): #从prices.txt读取价格数据 global nt, nInst df = pd.read_csv(fn, sep='\s+', header=None, index_col=None) nt, nInst = df.values.shape return (df.values).T pricesFile = "./prices.txt" prcAll = loadPrices(pricesFile) #数据存储在prcAll中 # 按实际股票数量初始化独立子列表 pChange = [[] for _ in range(nInst)] for j, stock in enumerate(prcAll): for i in range(1,5,1): temp = prcAll[j][i] / prcAll[j][i-1] pChange[j].append(temp)
如果业务逻辑确实只需要处理前20只股票,直接在外层循环截断遍历范围即可,比如写成
for j, stock in enumerate(prcAll[:20]):,只要保证列表初始化长度和实际遍历的元素数量一致,就不会触发索引越界。
内容的提问来源于stack exchange,提问作者Shotty
相关产品推荐
相关产品推荐

