2016-11-28 34 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