226 votes

Comment modifier les entrées d'une liste pendant une boucle for ?

Je sais maintenant qu'il n'est pas sûr de modifier la liste au cours d'un bouclage itératif. Cependant, supposons que j'aie une liste de chaînes de caractères et que je veuille dépouiller les chaînes elles-mêmes. Le remplacement des valeurs mutables est-il considéré comme une modification ?


Voir <a href="https://stackoverflow.com/questions/15363138">Portée d'une variable python dans une boucle for </a>pour un problème connexe : l'affectation au <em>variable d'itération </em>ne modifie pas la séquence sous-jacente et n'a pas non plus d'impact sur l'itération future.

235voto

martineau Points 21665

Comme la boucle ci-dessous ne fait que modifier des éléments déjà vus, elle serait considérée comme acceptable :

a = ['a',' b', 'c ', ' d ']

for i, s in enumerate(a):
    a[i] = s.strip()

print(a) # -> ['a', 'b', 'c', 'd']

Ce qui est différent de :

a[:] = [s.strip() for s in a]

en ce sens qu'elle ne nécessite pas la création d'une liste temporaire et l'affectation de celle-ci en remplacement de l'originale, bien qu'elle exige davantage d'opérations d'indexation.

Attention : Bien que vous puissiez modifier De cette façon, vous ne pouvez pas modifier le nombre d'éléments dans la liste de contrôle. list sans risquer de rencontrer des problèmes.

Voici un exemple de ce que je veux dire : la suppression d'une entrée perturbe l'indexation à partir de ce moment-là :

b = ['a', ' b', 'c ', ' d ']

for i, s in enumerate(b):
    if s.strip() != b[i]:  # leading or trailing whitespace?
        del b[i]

print(b)  # -> ['a', 'c ']  # WRONG!

(Le résultat est erroné car il n'a pas supprimé tous les éléments qu'il aurait dû supprimer).

Mise à jour

Cette réponse étant assez répandue, voici comment supprimer efficacement des entrées "sur place" (même si ce n'est pas exactement la question) :

b = ['a',' b', 'c ', ' d ']

b[:] = [entry for entry in b if entry.strip() == entry]

print(b)  # -> ['a']  # CORRECT

Voir Comment supprimer des éléments d'une liste lors de l'itération ? .

165voto

Ignacio Vazquez-Abrams Points 312628

C'est considéré comme une mauvaise forme. Utilisez plutôt une compréhension de liste, avec une affectation de tranche si vous devez conserver les références existantes à la liste.

a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)

26voto

eugene.shatsky Points 48

Une autre variante de boucle for, qui me semble plus propre qu'une boucle avec enumerate() :

for idx in range(len(list)):
    list[idx]=... # set a new value
    # some other code which doesn't let you use a list comprehension

15voto

JackWu Points 330

La modification de chaque élément lors de l'itération d'une liste est acceptable, tant que vous ne modifiez pas les éléments ajoutés/supprimés à la liste.

Vous pouvez utiliser la compréhension des listes :

l = ['a', ' list', 'of ', ' string ']
l = [item.strip() for item in l]

ou simplement faire le C-style pour la boucle :

for index, item in enumerate(l):
    l[index] = item.strip()

5voto

Rafael Monteiro Points 63

En répondre donnée par Ignacio Vazquez-Abrams est très bonne. Elle peut être illustrée par l'exemple suivant. Imaginez que :

  1. Une liste de deux vecteurs vous est donnée.
  2. Vous souhaitez parcourir la liste et inverser l'ordre de chacun des tableaux.

Disons que vous avez :

v = np.array([1,2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
    i = i[::-1]   # This command does not reverse the string.

print([v,b])

Vous recevrez :

[array([1, 2, 3, 4]), array([3, 4, 6])]

D'autre part, si vous le faites :

v = np.array([1,2,3,4])
b = np.array([3,4,6])

for i in [v, b]:
   i[:] = i[::-1]   # This command reverses the string.

print([v,b])

Le résultat est le suivant :

[array([4, 3, 2, 1]), array([6, 4, 3])]

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