Python 列表索引超出范围错误

1 投票
2 回答
961 浏览
提问于 2025-04-17 19:56

我正在尝试用Python测试一个简单的二维地图坐标生成器。它会创建一个Tile对象,并用x和y数组来存储坐标,这样我就可以访问这些坐标并修改它们的属性。

这个程序会创建一个地图对象,并在一个二维坐标平面上填充瓷砖。

map = [[ Tile(True)
    for y in range(MAP_HEIGHT) ]
        for x in range(MAP_WIDTH) ]

这是瓷砖类:

class Tile:
    #a tile of the map and its properties
    def __init__(self, blocked, type, owner, block_sight = None):
        self.blocked = blocked
        self.type = type
        self.owner = owner 
        if block_sight is None: block_sight = blocked
        self.block_sight = block_sight

我试着让程序逐个字符读取一个文本文件,以创建地图。它会根据mapx和mapy提供的坐标在地图上插入一个对象。

mapx = 0
mapy = 0
filename = str(mapn) + '.txt'
new_map = [[ Tile(True, 0, 0)
         for y in range(MAP_HEIGHT) ]
       for x in range(MAP_WIDTH) ]
with open(filename) as f:
    while True:
        c = f.read(1)
        if not c:
            return new_map
        elif (c == '#'):
            new_map[mapx][mapy].blocked = False
            new_map[mapx][mapy].block_sight = True
            new_map[mapx][mapy].type = 0
            new_map[mapx][mapy].owner = 0

(在添加了几个elif之后)

if(mapx < MAP_WIDTH):
    mapx += 1
elif(mapy < MAP_HEIGHT):
    mapy += 1
    mapx = 0

运行这个程序时,我遇到了一个错误:IndexError: list index out of range。 错误提示说

 new_map[mapx][mapy].blocked = False 

这一行出了问题。你知道我哪里做错了吗?

2 个回答

0

如果你先读取文件,然后创建一个列表 [ ... (xi, yi) ... ],再对这个 (xi, yi) 进行循环来实例化 Tile 对象,这样会更符合 Python 的风格。这样做的话,你就不用去考虑列表的索引问题了。

这只是我个人的一点看法...

2

初始化之后,外层列表会有 MAP_WIDTH 个元素,索引从 0 到 MAP_WIDTH-1。同样,每个内层列表的索引范围是从 0 到 MAP_HEIGHT-1

想象一下,当 mapx = MAP_WIDTH-1 时,也就是你代码中的列表末尾会发生什么:

if(mapx < MAP_WIDTH):
    mapx += 1
....

此时,mapx 的值会超过列表的最大索引。

为了避免这个问题,条件判断应该改成 mapx < MAP_WIDTH-1。而且,elif 中的判断也需要相应地进行修改。

撰写回答