2014-09-18 9 views
1

Этот код работаетIndexError: список индексов вне диапазона при удалении дубликатов

X = ['jennifer', 1, 1, 2, 'apple', 3, 3, 1, 'apple', ['true', 'burps','taste', 'good'], ['true', 'burps', 'taste', 'good'], 3, 'jennifer'] 

for index in reversed(range(len(X))): 
    if X.count(X[index]) > 1: 
     X.remove(X[index]) 

давая мне список, без дублей

[2, 1, 'apple', ['true', 'burps', 'taste', 'good'], 3, 'jennifer'] 

Я просто не понимаю, почему это работает только при переходе в задний ход. Почему не следующее то же самое?

for i in range(0,len(X)): 
    if X.count(X[i]) > 1: 
     X.remove(X[i]) 

Я получаю сообщение об ошибке

if X.count(X[i]) > 1: 
IndexError: list index out of range 

В любом случае я удаление элемента из списка я читал, так почему бы первый пример не выходит из диапазона, но второй один будет? Могу ли я сделать что-то во втором примере, чтобы заставить его работать?

ответ

1

Нет, ваш второй пример не будет работать. Причина, по которой работает обратная версия, заключается в том, что в худшем случае вы получаете доступ только к элементу списка «LAST».

Итак, у X есть 5 элементов и все дубликаты, поэтому вы удаляете все элементы до тех пор, пока не останется один из них. Сначала len(X) равно 5, поэтому ваш цикл for-loop будет зацикливаться на 4 3 2 1 0. Каждый раз, когда вы удаляете 1 элемент, список уменьшается на 1. Таким образом, максимальный индекс, к которому вы можете получить доступ, начинается с 4, затем сжимается до 3, 2, 1, 0, что соответствует последовательности, к которой вы обращаетесь к списку, поэтому вы выиграли У меня есть IndexError.

Таблица значений индекса, а максимальный индекс доступен из X в каждом шаге:

index Max. index of X 
4  4 
3  3 
2  2 
1  1 
0  0 

Если попытаться удалить более 1 элементы (. Например, все дубликаты в 1 шаг) Каждый раунд , вы можете снова увидеть IndexError.

1

Это не очень хорошая идея, чтобы изменить список в то время как итерация через него, как в:

for i in range(0,len(X)): 
if X.count(X[i]) > 1: 
    X.remove(X[i]) 

Одним из вариантов является создание списка с теми, которые вы хотите удалить, а затем повторять снова копирование, кто не в этом список.

Другой вариант - использовать set object, который не допускает дубликатов.

+0

Это, вероятно, так, но я работаю над идеей о том, что списки являются изменяемыми, и я уверен, что это можно сделать так: я просто пропустил, как это сделать. – JMJ

+0

Лучшим вариантом является повторение итерации назад, как говорит другой anwser. Но вы все равно можете использовать объект set, который не позволяет дублировать. – lucasmullerm

1

Вы изменяете список во время итерации, поэтому каждый раз, когда вы удаляете что-то вперед, вы уменьшаете его len, и к концу вашей итерации ваши индексы будут за пределами допустимого диапазона. Возвращаясь назад, вы не сталкиваетесь с этой проблемой.

Смежные вопросы