2016-07-24 4 views
0

리스트에서 중복을 제거하려고합니다. 나는 아래 코드로 그렇게하려고 노력하고있다.Python 3 : IndexError :리스트 인덱스가 범위를 벗어났습니다.

>>> X 
['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b'] 
>>> for i in range(X_length) : 
... j=i+1 
... if X[i] == X[j] : 
... X.pop([j]) 

하지만

Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
IndexError: list index out of range 

이 도와주세요 얻고있다.

+0

일부 코드가 누락 되었습니까? 'j' 란 무엇입니까? 어쨌든, 나는 당신이 가면서 마지막으로 짧아지고 있다는 것이 문제라고 생각합니다. 'i'가 최대 값에 도달 할 때까지 목록은 더 이상 길지 않으므로 색인 오류가 발생합니다. – smarx

+0

X_length 및 j는 무엇입니까? – kaitian521

+0

'X_length'는 무엇입니까? 'j' 란 무엇입니까? 'X.pop ([j])'는 무엇입니까? –

답변

2

목록에서 항목을 제거하기 시작하면 크기가 변경됩니다. 따라서, 인덱스 번째 i는 더 이상 특정 제거 후 존재하지 않을 수 있습니다

>>> x = ['a', 'b', 'c', 'd', 'e'] 
>>> x[4] 
'e' 
>>> x.pop() 
'e' 
>>> x[4] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: list index out of range 

중복 항목을 제거하는 간단한 방법은 고유 항목 만 포함 할 수있는 set에 목록을 변환하는 것입니다. 목록으로 지정해야하는 경우 목록으로 다시 변환 할 수 있습니다 (list(set(X))). 그러나 주문은 여기에 보존되지 않습니다.


당신은 연속 중복을 제거 하지 중복 된 항목 저장하는 새로운 배열 사용을 고려할 경우 바인딩 우리의 범위는 달리하기 때문에, 우리는을 초과 len(x) - 1입니다

unique_x = [] 
for i in range(len(x) - 1): 
    if x[i] != x[i+1]: 
     unique_x.append(x[i]) 
unique_x.append(x[-1]) 

x[i+1]을 사용할 때 배열 범위.

+0

입력리스트의 아이디는'[ 'a', 'b', 'c', 'd', 'e', ​​'f', 'a', 'b', 'a' ? 출력은'[ 'a', 'b', 'c', 'd', 'e', ​​'f', 'a', 'b', 'a']' – SilentMonk

+0

@SilentMonk 예, 마지막 값을 새 목록에 추가하는 한. –

0

일반적으로 시퀀스가 ​​계속 변경 될 것이므로 반복하는 동안 시퀀스를 변경하는 것이 좋습니다. 다음은 몇 가지 다른 방법은 다음과 같습니다 감안할 때

:

list(set(X)) 
['a', 'c', 'b', 'e', 'd', 'f'] 
:

X = ['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b'] 

당신은 (그리고 순서는를 중요하지 않습니다) 목록에서 중복을 제거에만 관심이 있다면, 당신은 설정을 사용할 수 있습니다


당신이 질서를 유지하고 목록의 아무 곳이나을 중복을 제거하려는 경우, 당신이 그것을 할 수 생이하면서 새로운리스트 : 당신이 연속 중복을 제거하려는 경우

X_new = [] 
for i in X: 
    if i not in X_new: 
     X_new.append(i) 

X_new 
# Out: ['a', 'b', 'c', 'd', 'e', 'f'] 

, smarx의 대답 @ 고려하십시오.

0

목록의 마지막 반복에서 j의 값은 길이가 될 i + 1으로 설정되며이 경우 길이는 8입니다. 그런 다음 X[j]에 액세스하려고 시도하지만 j은 목록 끝 부분에 있습니다.

대신, 단순히 세트 목록을 변환 :

>>> set(X) 
{'e', 'f', 'd', 'c', 'a', 'b'} 

을 당신이 다른 곳에 ordered set에보고해야하는 경우 순서를 보존 할 필요가없는 경우.

2

@ Rushy의 대답은 훌륭하고 아마도 내가 권하는 것입니다.

연속 복제본을 제거하려는 경우 (위치를 변경하지 않고 목록을 수정하여)을 작성하려는 경우 한 가지 공통적 인 방법은 목록을 거꾸로 작업하는 것입니다 :

def remove_consecutive_duplicates(lst): 
    for i in range(len(lst) - 1, 1, -1): 
     if lst[i] == lst[i-1]: 
      lst.pop(i) 

x = ['a', 'b', 'b', 'c', 'd', 'd', 'd', 'e', 'f', 'f'] 
remove_consecutive_duplicates(x) 
print(x) # ['a', 'b', 'c', 'd', 'e', 'f'] 

목록의 끝에서 시작하여 뒤로 이동하여, 당신은 당신이 그것을 단축했기 때문에 목록의 끝을 실행의 문제를 피할 수 있습니다.

예. 당신이 'AABC'로 시작하고 앞으로 이동하는 경우, 당신은 인덱스 0, 1, 2 사용할 것, 뒤로 이동 3.

0 
| 
aabc 

(Found a duplicate, so remove that element.) 

1 
| 
abc 

    2 
    | 
abc 

    3 
    | 
abc <-- Error! You ran off the end of the list. 

, 당신은 인덱스 3, 2, 1을 사용합니다, 0 :

3 
    | 
aabc 

    2 
    | 
aabc 

1 
| 
aabc 

(Found a duplicate so remove that element.) 

0 
| 
abc <-- No problem here! 
관련 문제