Удалить элемент из списка - PullRequest
0 голосов
/ 21 июля 2010

Эй, я пытался удалить элемент из списка (без использования set):

list1 = []
for i in range(2,101):
    for j in range(2,101):
        list1.append(i ** j)
list1.sort()
for k in range(1,len(list1) - 1):
    if (list1[k] == list1[k - 1]):
        list1.remove(list1[k])
print "length = " + str(len(list1))

Функция set работает нормально, но я хочу применить этот метод. За исключением того, что я получаю:

 IndexError: list index out of range

по заявлению:

 if (list1[k] == list1[k - 1]):

Отредактировано для добавления (Спасибо Неду Батчелдеру) рабочий код:

list1 = []
for i in range(2,101):
 for j in range(2,101):
   list1.append(i ** j)
list1.sort()
k = 0
while k < len(list1) - 1: # while loop instead of for loop because "The range function is evaluated once before the loop is entered"
 k += 1
 if (list1[k] == list1[k - 1]):
  list1.remove(list1[k])
  list1.sort()
  k -= 1 # "If you find a duplicate, you don't want to move onto the next iteration, since you'll miss potential runs of more than two duplicates"
print "length = " + str(len(list1))

Ответы [ 4 ]

5 голосов
/ 21 июля 2010

Ваш код не работает, потому что в вашем цикле вы перебираете все индексы в исходном списке, но сокращаете список по мере продвижения.В конце итерации вы получите доступ к индексам, которые больше не существуют:

for k in range(1,len(list1) - 1):
    if (list1[k] == list1[k - 1]):
        list1.remove(list1[k])

Функция range оценивается один раз перед вводом цикла, создавая список всех индексов в списке,Каждый вызов remove сокращает список на один, поэтому, если вы удалите какие-либо элементы, вы гарантированно получите ошибку в конце списка.

Если вы хотите использовать такой цикл,try:

k = 1
while k < len(list1):
    if list1[k] == list1[k-1]:
        del list1[k]
    else:
        k += 1

Я исправил несколько других вещей:

  1. Вам не нужны скобки вокруг условия в операторах Python if.
  2. Если вы найдетедубликат, вы не хотите переходить к следующей итерации, так как вы пропустите потенциальные прогоны более двух дубликатов.
  3. Вы хотите начать с индекса 1, а не с нуля, так как k = 0 будетсписок доступа1 [-1].
3 голосов
/ 21 июля 2010

Выглядит так, как будто вы пытаетесь унифицировать список (уточнение было бы замечательно), поэтому посмотрите здесь: http://www.peterbe.com/plog/uniqifiers-benchmark

Здесь также есть вопрос о SO: В Python, какой самый быстрый алгоритм удаления дубликатов из списка, чтобы все элементы были уникальными * при сохранении порядка *?

2 голосов
/ 21 июля 2010

Вместо удаления элементов Напишите в своем списке понимание того, что вы хотите, в новом списке:

list1[:] = [list1[k] for k in range(1,len(list1) - 1) 
                     if not list1[k] == list1[k - 1] ]

Ваш метод ломается, потому что вы удаляете элементы из списка.Когда вы это сделаете, список станет короче , и следующая итерация цикла пропустит элемент.Скажем, вы смотрите на k = 0 и L = [1,2,3].Вы удаляете первый элемент, поэтому L = [2,3], а следующий k = 1.Итак, вы смотрите на L [1], который равен 3 - вы пропустили 2!

Итак: Никогда не меняйте список, для которого вы повторяете

1 голос
/ 21 июля 2010

Вы можете использовать del:

l = [1, 2, 3, 4]
del l[2]
print l
[1, 2, 4]
...