"list out of range" 尝试删除列表列表中的行时抛出 list[i][0] 和 list[i][1] == 0

"list out of range" thrown when trying to remove rows in list of list where list[i][0] and list[i][1] == 0

我正在尝试删除数组中前两列具有 0 值的行。我的代码是:

  for i in range (5680):
        if games[i][0] == 0 and games[i][1] == 0:                   
            games.pop(i)
  print(games)

games[i][0]games[i][1] 的打印语句放在第二行下方会打印出一大堆 0 行,所以我知道这些行确实 exist.I 收到 list out of range 错误,即使 games 是 5680 by 5 矩阵。 无论我尝试更改什么,仍然会抛出错误。怎么回事?

如果您要从 games 中删除行(就像您对 games.pop(i) 所做的那样),它将不再有 5680 行,所以只要您至少删除 1 行,并且您最终尝试访问 games[5679],这会给你 'list out of range',因为你不再有那么多行。

一旦调用 games.pop(i)games 矩阵的维度就会从 5680x5 变为 5679x5,并随着每次连续调用而减小。同时,for i in range(5680)不断迭代[0, ..., 5680],也就是说后面的i一定会超出范围。

有多种方法可以防止这种情况发生。一种简单的方法是以相反的顺序检查 games 的索引。这样,如果索引 game_index 被弹出,迭代中的下一个索引 game_index - 1 仍将存在于矩阵中。

# iterate in reverse order
for i in range(5680, 0, -1):
    game_index = i-1
    if games[game_index][0] == 0 and games[game_index][1] == 0:
        games.pop(game_index)

print(games)

如果您希望只弹出几个项目,这个过程通常很好。如果您希望弹出大部分项目,创建一个新列表可能会更高效。

games = [game for game in games if game[0] != 0 and game[1] != 0]

您在遍历列表时正在更改列表。 这失败了。弹出第一项后,列表中不再有 5680 个元素,因此您无法访问最后这些元素。

而是使用 filter 操作来生成新列表。

new_games = filter(lambda row: row[0] != 0 or row[1] != 0, games)

Handy examples

尝试更改您正在迭代的对象几乎总是一个坏主意。在第一个 pop() 之后的情况下,您的列表已经小于 5680。因此,当您到达 5679 时,您已经超出范围。

试试这个:

games = [g for g in games if g[0] != 0 or g[1] != 0]

games = list(filter(lambda g: g[0] != 0 or g[1] !=0, games))