2016-11-28 6 views
0

0이있는 배열의 행을 제거하려고합니다. 처음 두 열의 값. 내 코드는 다음과 같습니다list [i] [0] 및 list [i] [1] == 0 목록의 행에서 행을 제거하려고 할 때 "list out of range"가 throw 됨

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

이 두 번째 줄은 0 년대의 라인의 전체 무리를 출력 아래에 games[i][0]games[i][1]의 인쇄 문을 퍼팅 그래서 나는 이러한 행은 exist.I가 list out of range 오류를 얻고있다 할 것을 알고있다 게임이 행렬 인 경우에도 마찬가지입니다. 오류를 변경하려고해도 문제가 계속 발생합니다. 무슨 일이야?

+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)와 마찬가지로) 더 이상 5680 행, 너무 오래 제거 적어도 1 행이 없습니다, 당신은 결국 어떤을 줄 것이다, 액세스 games[5679]하려고 games에서 행을 제거하는 경우 당신은 더 이상 그 많은 행을 가지고 있지 않기 때문에 당신은 범위를 벗어났습니다.

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