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

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))

问题原因

  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],导致索引越界。
  2. 构造方法命名错误:类的构造方法应该是__init__(双下划线),当前写成init,导致初始化逻辑不会自动执行,虽手动调用_lag_tomt_rutenett暂时规避,但属于潜在bug。
  3. 遍历获取索引的隐患: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:45:55