Il y a un problème avec la suppression d'éléments successifs d'une liste. Par exemple, j'ai une liste;
found @ in word :@someword found @ in word :@otherword
Je veux supprimer de la liste les éléments qui ont @ char.
a = ['aaaaa', '@someword', 'qqqq', '@otherword','bbbb']
La sortie est; (trouvé seulement le premier élément, ignoré le deuxième.)
found @ in word :@someword
si j'ajoute une valeur entre cet élément;
a = ['aaaaa', '@someword', '@otherword','bbbb']
for word in a:
if '@' in word:
print("found @ in word :" +word)
a.remove(word)
Il en attrape deux;
['aaaaa', '@someword', '@otherword','bbbb',...]
Je débogue le code, s'il y a des mots successifs qui incluent @ char, remove function ignore le second, à cause du changement d'index après la suppression du processus.
comment puis-je supprimer ces mots?
6 Réponses :
Vous pouvez utiliser une compréhension de liste pour filtrer les éléments en fonction d'une condition:
>>> replaced = [item if '@' not in item else '' for item in original] >>> replaced ['aaaaa', '', '', 'bbbb']
Ou les remplacer:
>>> original = ['aaaaa', '@someword', '@otherword','bbbb'] >>> filtered = [item for item in original if '@' not in item] >>> filtered ['aaaaa', 'bbbb']
Voir documentation pour plus d'informations. J'espère que ça aide!
Vous ne devriez jamais modifier une liste que vous parcourez, mais plutôt en créer une nouvelle:
b = [word for word in a if not '@' in word]
vous devez ajouter la liste «a» dans une liste. Le code ci-dessous peut vous aider
a = ['aaaaa', '@someword', '@otherword','bbbb']
for word in list(a):
if '@' in word:
print("found @ in word :" +word)
a.remove(word)
word = ['aaaaa', '@someword', '@otherword','bbbb'] filtered = list(filter( lambda x : '@' not in x ,word)) another way is you can user filter
Il n'est pas conseillé de modifier l'élément d'une liste pendant que vous la parcourez.
a = ['aaaaa', '@someword', 'qqqq', '@otherword','bbbb'] new_list = [i for i in a if '@' not in i] print(new_list) # ['aaaaa', 'qqqq', 'bbbb']
Le résultat de ceci est
(0, 'aaaaa') (1, '@someword') ['aaaaa', 'qqqq', '@otherword', 'bbbb'] (2, '@otherword') ['aaaaa', 'qqqq', 'bbbb']
À partir de là, vous pouvez voir que '@someword' est supprimé et que l'élément à l'index 2 n'est plus '@otherword', il est maintenant 'bbbb'. Par conséquent, '@otherword' ne peut pas être supprimé.
Le deuxième exemple que vous avez donné fonctionne car lorsque vous supprimez '@someword' l'élément à l'index 2 devient '@otherword', il peut donc être supprimé à l'itération suivante .
(0, 'aaaaa') (1, '@someword') ['aaaaa', '@otherword', 'bbbb'] (2, 'bbbb')
Je vous conseille de créer une nouvelle liste et de stocker simplement les éléments qui ne contiennent pas de '@'
a = ['aaaaa', '@someword', '@otherword','bbbb']
for index,word in enumerate(a):
print(index, word)
if '@' in word:
a.remove(word)
print(a)
Le problème réel ici est que vous parcourez une liste que vous éditez (suppression / ajout d'éléments). Cela signifie que lorsque vous supprimez l'élément 2 alors que vous êtes sur le deuxième élément, vous atteindrez alors l'élément 4 dans l'itération suivante.
Les solutions sont de boucler sur une copie de la liste, ou de créer une copie de la liste et renvoyer cela (avec la compréhension de la liste par exemple)
Une copie de la liste peut être créée avec word[: .
a = ['aaaaa', '@someword', '@otherword','bbbb']
for word in a[:]:
if '@' in word:
print("found @ in word :" +word)
a.remove(word)
Vous ne devez jamais modifier la liste que vous parcourez
Alors, comment puis-je le faire?
Cela fonctionne en c ou java, quelle est la différence logique de la liste python?
En fait, je ne sais pas quelle est la différence; Je ne suis pas un programmeur professionnel et seulement à l'aise avec python. Mais je pense que ce n'est toujours pas une bonne pratique en C ou Java
Double possible de Comment supprimer des éléments d'une liste lors de l'itération? < / a>