116 votes

Comment supprimer des éléments de liste dans une boucle for en Python ?

J'ai une liste

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

Je veux supprimer les éléments de cette liste dans une boucle for comme ci-dessous :

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

Mais ça ne marche pas. Qu'est-ce que je peux faire ?

169voto

NPE Points 169956

Vous n'êtes pas autorisé à supprimer des éléments de la liste tout en l'itérant à l'aide d'une fonction for boucle.

La meilleure façon de réécrire le code dépend de ce que vous essayez de faire.

Par exemple, votre code est équivalent à :

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

Vous pouvez également utiliser un while boucle :

while a:
    print(a.pop())

J'essaie de supprimer des éléments s'ils correspondent à une condition. Ensuite, je passe à l'élément suivant.

Vous pourriez copier chaque élément qui n'a pas correspondant à la condition dans une deuxième liste :

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

Alternativement, vous pouvez utiliser filter ou une liste de compréhension et réaffecter le résultat à a :

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

ou

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

... représente la condition que vous devez vérifier.

98voto

Alex L Points 3048

Itérer dans une copie de la liste :

>>> 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']

29voto

lvc Points 12046

Comme d'autres réponses l'ont dit, la meilleure façon de procéder consiste à créer une nouvelle liste - soit en itérant sur une copie, soit en construisant une liste avec seulement les éléments que vous voulez et en la réaffectant à la même variable. La différence entre ces deux méthodes dépend de votre cas d'utilisation, car elles affectent différemment les autres variables de la liste originale (ou plutôt, la première les affecte, la seconde non).

Si, pour une raison ou une autre, la copie n'est pas envisageable, il existe une autre option qui repose sur la compréhension des raisons pour lesquelles la modification d'une liste en cours d'itération ne fonctionne pas. L'itération de liste fonctionne en gardant la trace d'un index, l'incrémentant à chaque fois autour de la boucle jusqu'à ce qu'il tombe à la fin de la liste. Ainsi, si vous supprimez à (ou avant) l'indice actuel, tout ce qui se trouve entre ce point et la fin se déplace d'une place vers la gauche. Mais l'itérateur n'est pas au courant de cela, et il saute effectivement l'élément suivant puisqu'il est maintenant à l'index actuel. actual plutôt que le suivant. Cependant, la suppression des éléments qui sont après l'indice actuel n'affecte pas les choses.

Cela implique que si vous itérez la liste d'avant en arrière, si vous supprimez un élément à l'index actuel, tout ce qui se trouve à sa droite se déplace vers la gauche - mais cela n'a pas d'importance, puisque vous avez déjà traité tous les éléments à droite de la position actuelle, et que vous vous déplacez vers la gauche - le prochain élément à gauche n'est pas affecté par le changement, et donc l'itérateur vous donne l'élément que vous attendez.

TL;DR :

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

Cependant, il est généralement préférable de faire une copie pour faciliter la lecture de votre code. Je ne mentionne cette possibilité que par souci d'exhaustivité.

6voto

user3848191 Points 83
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)

Fonctionne : pour éviter de modifier la liste sur laquelle vous itérez, vous faites une copie de a , itérer sur elle et retirer les éléments de b . Ensuite, vous copiez b (la copie modifiée) à a .

3voto

cobie Points 1484

Pourquoi ne pas créer une nouvelle liste et ajouter les éléments que vous voulez à cette nouvelle liste. Vous ne pouvez pas supprimer des éléments en itérant dans une liste.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X