2016-11-28 111 views
0

我试图删除具有0的数组中的行前两列的值。我的代码是:尝试删除list [i] [0]和list [i] [1]列表中的行时抛出的“列表超出范围”== 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] print语句下的第二行打印出一大堆0的线,所以我知道这行做exist.I我得到一个错误list out of range ,即使游戏是由5矩阵5680。 无论我尝试更改错误仍然抛出。这是怎么回事?

+1

全部追溯和games'的'一个例子表示将是很好。 –

回答

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

明白了,谢谢! – tharvey

1

如果你从games删除行(如你games.pop(i)做),它将不再有5680行,所以只要删除至少1行,你最终尝试访问games[5679],这将给你'列出范围',因为你不再有那么多行。

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] 
0

你在迭代它时正在改变列表。 这失败了。一旦你弹出的第一个项目,你不再需要在列表5680点的元素,所以你不能访问这些最后的元素。

相反,使用过滤操作产生一个新的列表。

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

Handy examples

相关问题