2016-11-28 6 views
0

0の配列の行を削除しようとしています最初の2つの列の値。私のコードは次のとおりです。二行目の下にgames[i][0]games[i][1]のprint文を置く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) 

ので、私はこれらの行はexist.Iがlist out of rangeエラーを取得していないことを知って0年代のラインの全体の束を出力しますたとえゲームが56805行列であっても。 私が何を問題にしても、エラーはまだスローされます。どうしたの?

+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.pop(i)でそうであるように)gamesから行を削除している場合、それはもはやそれほど限り、あなたは、少なくとも1行を削除し、あなたが最終的にアクセスgames[5679]にしようと、与えるであろうように、5680行を持っていますあなたはもはやその行がないので、範囲外です。

1

games.pop(i)が呼び出されるとすぐに、gamesの行列の次元は5680x5から5679x5になり、連続する呼び出しごとに減少します。同時に、for i in range(5680)[0, ..., 5680]を繰り返し実行します。つまり、後でiが範囲外になることを意味します。

これを防ぐにはさまざまな方法があります。 1つの簡単な方法は、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

関連する問題