Python代码报错IndexError: list index out of range,求排查解决
Python网格代码索引越界问题排查与修复
问题说明
开发Python网格相关代码时,hent_celle方法出现列表索引越界错误,该方法接收网格坐标并返回对应位置的对象。调用_sett_naboer(2,1)时触发报错。
报错信息
Traceback (most recent call last): File "/Users/cc/Documents/Python/Oblig8/rutenettto.py", line 105, in <module> print(testobjekt._sett_naboer(2,1)) File "/Users/cc/Documents/Python/Oblig8/rutenettto.py", line 64, in _sett_naboer nabo_u_kol = self.hent_celle(rad+1,kol) File "/Users/cc/Documents/Python/Oblig8/rutenettto.py", line 43, in hent_celle return self._rutenett[rad][kol] IndexError: list index out of range
完整代码
from random import randint from celle import Celle class Rutenett: def init(self,rader,kolonner): self._ant_rader = int(rader) self._ant_kolonner = int(kolonner) self._rutenett = [] def _lag_tom_rad(self): liste = [] for x in range(self._ant_kolonner): liste.append(None) return liste def _lag_tomt_rutenett(self): liste2 = [] for x in range(self._ant_rader): liste_ = self._lag_tom_rad() liste2.append(liste_) self._rutenett = liste2 def lag_celle(self,rad,kol): celle = Celle() tilfeldig_tall = randint(0,100) if tilfeldig_tall <= 33: celle.sett_levende() return celle else: return celle def fyll_med_tilfeldige_celler(self): for x in self._rutenett: for y in x: rad = int(self._rutenett.index(x)) kol = int(x.index(y)) self._rutenett[rad][kol] = self.lag_celle(rad,kol) def hent_celle(self,rad,kol): if rad > self._ant_rader or kol > self._ant_kolonner or rad < 0 or kol < 0: return None else: return self._rutenett[rad][kol] def tegn_rutenett(self): for x in self._rutenett: for y in x: print(y.hent_status_tegn(), end="") def hent_alle_celler(self): liste = [] for x in self._rutenett: for y in x: liste.append(y) return liste def _sett_naboer(self,rad,kol): cellen = self.hent_celle(rad,kol) # lik linje nabo_v_rad = self.hent_celle(rad,kol-1) nabo_h_rad = self.hent_celle(rad,kol+1) # under nabo_u_kol = self.hent_celle(rad+1,kol) nabo_u_kol_h = self.hent_celle(rad+1,kol+1) nabo_u_kol_v = self.hent_celle(rad+1,kol-1) # over nabo_o_kol = self.hent_celle(rad-1,kol) nabo_o_kol_h = self.hent_celle(rad-1,kol+1) nabo_o_kol_v = self.hent_celle(rad-1,kol-1) liste = [nabo_v_rad,nabo_h_rad,nabo_u_kol_h,nabo_u_kol_v,nabo_o_kol,nabo_o_kol_h,nabo_o_kol_v] #print(liste) #print(nabo_o_kol_h) for x in liste: if x == None: pass else: cellen._naboer.append(x) return cellen._naboer def antall_levende(self): teller = 0 for x in self._rutenett: for y in x: if y._status == "doed": pass else: teller +=1 return teller testobjekt = Rutenett(3,3) testobjekt._lag_tomt_rutenett() testobjekt.fyll_med_tilfeldige_celler() print(testobjekt._sett_naboer(2,1))
问题原因
- 边界判断逻辑错误:
hent_celle方法中判断索引是否越界的条件为rad > self._ant_rader or kol > self._ant_kolonner,但Python列表索引从0开始,比如3行的网格,行索引范围是0-2,当rad等于self._ant_rader(即3)时,rad > self._ant_rader不成立,会尝试访问self._rutenett[3],导致索引越界。 - 构造方法命名错误:类的构造方法应该是
__init__(双下划线),当前写成init,导致初始化逻辑不会自动执行,虽手动调用_lag_tomt_rutenett暂时规避,但属于潜在bug。 - 遍历获取索引的隐患:
fyll_med_tilfeldige_celler中用self._rutenett.index(x)和x.index(y)获取行列索引,当网格中有重复元素时,index会返回第一个匹配项的索引,导致赋值错误。
修复方案
1. 修正hent_celle的边界判断
将判断条件改为rad >= self._ant_rader or kol >= self._ant_kolonner or rad < 0 or kol < 0,确保索引超出有效范围时直接返回None:
def hent_celle(self,rad,kol): if rad >= self._ant_rader or kol >= self._ant_kolonner or rad < 0 or kol < 0: return None else: return self._rutenett[rad][kol]
2. 修正构造方法命名
将init改为__init__,确保类实例化时自动初始化属性:
def __init__(self,rader,kolonner): self._ant_rader = int(rader) self._ant_kolonner = int(kolonner) self._rutenett = []
实例化Rutenett(3,3)时会自动初始化,无需手动调用_lag_tomt_rutenett。
3. 优化索引遍历方式
用enumerate遍历网格,直接获取行列索引,避免index方法的隐患:
def fyll_med_tilfeldige_celler(self): for rad_idx, rad in enumerate(self._rutenett): for kol_idx, celle in enumerate(rad): self._rutenett[rad_idx][kol_idx] = self.lag_celle(rad_idx, kol_idx)
验证
修复后调用testobjekt._sett_naboer(2,1)时,rad+1=3会触发rad >= self._ant_rader(3>=3),返回None,不会尝试访问越界索引,错误即可解决。
内容的提问来源于stack exchange,提问作者datt
相关产品推荐
相关产品推荐

