Как удалить элементы списка в для цикла в Python? [дубликат]

Этот вопрос уже имеет ответ здесь:

У меня есть список

a = ["a", "b", "c", "d", "e"]

Я хочу удалить элементы в этом списке в для цикла как ниже:

for item in a:
    print item
    a.remove(item)

Но это не работает. Что я могу сделать?

62
задан 19 May 2012 в 17:43

6 ответов

Нельзя удалить элементы из списка при итерации по нему с помощью for цикл.

лучший способ переписать код зависит от того, что это, Вы пытаетесь сделать.

, Например, Ваш код эквивалентен:

for item in a:
  print item
a[:] = []

, С другой стороны, Вы могли использовать while цикл:

while a:
  print a.pop(0)

я пытаюсь удалить объекты, если они соответствуют условию. Затем я перехожу к следующему объекту.

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

result = []
for item in a:
  if condition is False:
    result.append(item)
a = result

, С другой стороны, Вы могли использовать filter или понимание списка и присвоить результат назад a:

a = filter(lambda item:... , a)

или

a = [item for item in a if ...]

, где ... обозначает условие, которое необходимо проверить.

99
ответ дан 31 October 2019 в 13:18

Выполните итерации через копию списка:

>>> a = ["a", "b", "c", "d", "e"]
>>> for item in a[:]:
    print item
    if item == "b":
        a.remove(item)

a
b
c
d
e
>>> print a
['a', 'c', 'd', 'e']
53
ответ дан 31 October 2019 в 13:18
import copy

a = ["a", "b", "c", "d", "e"]

b = copy.copy(a)

for item in a:
    print item
    b.remove(item)
a = copy.copy(b)

Работы: чтобы не изменять список, Вы выполняете итерации на, Вы делаете копию a, выполняете итерации по ней и удаляете объекты от b. Затем Вы копируете b (измененная копия) назад к a.

4
ответ дан 31 October 2019 в 13:18

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

, Если копия не является опцией по некоторым причинам, у Вас действительно есть еще одна опция, которая полагается на понимание того, почему, изменяя список Вы выполняете итерации повреждений. Повторение списка работает путем отслеживания индекс, постепенного увеличения его каждый раз вокруг цикла, пока он не падает с конца списка. Так, если Вы удаляете в (или прежде) текущий индекс, все от той точки, пока конец не смещает одно место налево. Но итератор не знает об этом и эффективно пропускает следующий элемент, так как это теперь в текущее индекс, а не следующий. Однако удаление вещей, которые являются после текущий индекс, не влияет на вещи.

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

TL; DR:

>>> a = list(range(5))
>>> for b in reversed(a):
    if b == 3:
        a.remove(b)
>>> a
[0, 1, 2, 4]

Однако создание копии обычно лучше с точки зрения создания Вашего кода, легкого читать. Я только упоминаю эту возможность ради полноты.

18
ответ дан 31 October 2019 в 13:18

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

3
ответ дан 31 October 2019 в 13:18

Вероятно, немного поздно для ответа на это, но я просто нашел этот поток, и я создал свой собственный код для него ранее...

    list = [1,2,3,4,5]
    deleteList = []
    processNo = 0
    for item in list:
        if condition:
            print item
            deleteList.insert(0, processNo)
        processNo += 1

    if len(deleteList) > 0:
        for item in deleteList:
            del list[item]

Это может быть длинным путем сделать его, но, кажется, работает хорошо. Я создаю второй список, который только содержит числа, которые касаются элемента списка для удаления. Обратите внимание, что "вставка" вставляет число элемента списка в положении 0 и продвигает остаток вперед поэтому при удалении объектов, список удален из самого большого количества назад к самому низкому количеству, таким образом, список остается в последовательности.

1
ответ дан 31 October 2019 в 13:18

Другие вопросы по тегам:

Похожие вопросы: