我正在尝试删除数组中前两列有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
行,所以我知道这些行确实存在。我是即使游戏是list out of range
个5680
矩阵,也会出现5
错误。
无论我尝试什么,仍然会抛出更改错误。怎么回事?
答案 0 :(得分:1)
如果您要从games
删除行(与games.pop(i)
一样),它将不再有5680行,因此只要删除至少1行,最终尝试访问games[5679]
,这会让您列出超出范围'因为你不再拥有那么多行。
答案 1 :(得分:1)
一旦调用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]
答案 2 :(得分:1)
尝试更改正在迭代的对象几乎总是一个坏主意。在你的情况下,在第一个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))
答案 3 :(得分:0)
您在迭代时改变列表。 这失败了。弹出第一个项目后,列表中不再有5680个元素,因此您无法访问这些元素。
而是使用过滤器操作生成新列表。
new_games = filter(lambda row: row[0] != 0 or row[1] != 0, games)