Удаление элементов из списка в цикле [дубликата]

1

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

a = [0, 1]
for i in a:
    z = a
    print z.remove(i)

Выход:

[1]

Результат, который я ожидал:

[1] 
[0]
  • 0
    Я не уверен, почему вы получаете какой-либо вывод. Я думал, что z.remove(i) вернется None .
Теги:
list

4 ответа

3
Лучший ответ

Это плохая практика изменить список, пока вы перекручивание через него †. Создайте копию списка. например:

oldlist = ['a', 'b', 'spam', 'c']
newlist = filter(lambda x: x != 'spam', oldlist)

† Чтобы понять, почему это может быть плохой практикой, рассмотрите детали реализации того, что происходит с итератором над последовательностью, когда последовательность изменяется во время итерации. Если вы удалили текущий элемент, должен ли итератор указывать на следующий элемент в исходном списке или на следующий элемент в измененном списке? Что делать, если ваша процедура принятия решения удаляет предыдущий (или следующий) элемент в текущий?


Некоторым людям не нравится фильтр, эквивалентная вещь со списком:

newlist = [x for x in oldlist if x != 'spam']
  • 0
    Используйте понимание списка вместо фильтра для этого метода.
8

Вы изменение списка во время прохода по нему - z = a не сделать копию, он просто указывает z на том же месте, a точки.

Пытаться

for i in a[:]:          # slicing a list makes a copy
    print i             # remove doesn't return the item so print it here
    a.remove(i)         # remove the item from the original list

или

while a:                # while the list is not empty
    print a.pop(0)      # remove the first item from the list

Если вам не нужен явный цикл, вы можете удалить элементы, которые соответствуют условию, с пониманием списка:

a = [i for i in a if i] # remove all items that evaluate to false
a = [i for i in a if condition(i)] # remove items where the condition is False
  • 0
    Выход теперь "Нет Нет"
  • 0
    remove ничего не возвращает, поэтому печатает None . Если вы хотите напечатать элемент перед его удалением, просто print i затем a.remove(i) . pop версия на самом деле возвращает элемент по указанному индексу, поэтому она будет print элемент. Отредактировал мой ответ, чтобы отразить это.
2

Проблема в том, что вы изменяете a с remove поэтому цикл выходит из-за того, что индекс уже находится за его пределами.

  • 0
    Так что он должен делать вместо этого?
  • 0
    Я не парень с питоном, поэтому мне нужно посмотреть синтаксис, но я предполагаю, что вы можете сделать некоторое while remove или while pop ?
Показать ещё 1 комментарий
1

Не пытайтесь удалить несколько элементов списка во время цикла списка. Я думаю, что это общее правило, за которым следует следить не только на питоне, но и на других языках программирования.

Вы можете добавить элемент для удаления в отдельный список. Затем удалите все объекты из этого нового списка из исходного списка.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню