9
votes

Problème Suppression d'éléments de liste dans A pour boucle (Python)

Dupliqué possible:
Supprimer des articles d'une liste lors de l'itération à Python < / p>

Bonjour, j'ai un problème que je ne peux pas sembler supprimer des objets tout en itérant à travers une liste de Python, Voici ce que j'ai: un titre doit être supprimé si un utilisateur entrait N ou N lorsqu'il a demandé à la question de supprimer la boucle de la boucle, le problème est que lorsque tout est terminé, les articles sont toujours là et aucun n'a été supprimé. ... xxx


1 commentaires

Aussi un DUP de Comportement étrange Python pour boucle ou liste . Et la solution de tranchée de liste semble être plus pythonique.


4 Réponses :


14
votes

Le code ci-dessous corrigera votre problème. Vous devez parcourir une copie de la liste. Vous ne pouvez pas supprimer les éléments de la liste que vous êtes itération.

import copy

def main():
    titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"]
    titles_list_orig = copy.deepcopy(titles_list)

    for title in titles_list_orig:
        print "Do you want to keep the title:", title , "\n or Delete it? Input Y for keep, N for Delete "
        Question = raw_input()
        if str(Question.upper()) == "N":
            titles_list.remove(title)

    print titles_list


8 commentaires

merci: d i utilisé épissure causer sa moins de lignes mais tu me conduis à avoir besoin de la copier merci


Pas besoin de le copier, il suffit de se déplacer dessus en sens inverse, de sorte que les déménagements n'affectent pas les éléments que vous voyez en itération.


@ncoghlan - Pouvez-vous s'il vous plaît élaborer votre réponse. pas clair pour moi.


Alternative à DeepCopy, vous pouvez également utiliser Orig = Liste (Titres) pour copier une liste :-)


@Wesley: a accepté, en fait, c'est plus approprié en général (c'est-à-dire pour des choses autres que des cordes), puisqu'il s'agit d'une copie peu profonde plutôt que d'une copie profonde. Nous n'avons pas besoin de copies du contenu de titles_list .


@Sumod J'ai élaboré un peu plus dans ma propre réponse.


ncoghlan. Belle façon de courir autour du design Python


Pourquoi voudriez-vous copier manuellement la liste lorsque vous pouvez déjà faire passer une copie avec pour titre dans titres_list [:] ?



8
votes

Votre code a deux problèmes majeurs.

Le premier est que vous n'êtes pas appeler em> la méthode code> supérieure code>, mais simplement la référencée. Vous devez réellement l'appeler (via question.upper () code>) comme W00T le fait dans sa réponse. P>

Mettre des relevés d'impression diagnostique à l'intérieur de votre boucle aurait été un bon moyen de voir que (surtout d'imprimer str (question.upper) code>) (tangent: question code> est un mauvais nom pour une variable qui détient la réponse à une question du programme demandé au programme Utilisateur) P>

Deuxièmement, supprimer des éléments déjà observés d'une liste que vous itération résultera de valeurs de saut. Vous n'avez pas vraiment besoin de copier la liste complète pour faire face à cela - il suffit d'Itération en sens inverse, c'est suffisant pour résoudre le problème. P>

Enfin, deux points de cosmétiques mineurs sont que Raw_Input () code> Accepte un argument d'invite, de sorte que vous n'avez pas besoin d'une instruction d'impression distincte et d'appeler supérieure () code> sur une chaîne renvoie lui-même une chaîne: p>

titles_list = ["English", "Math", "History", "IT", "Biology", "Spanish"]
prompt = ("Do you want to keep the title: {}\n"
          "or Delete it? Input Y for keep, N for Delete: ")

for title in reversed(titles_list):
    answer = raw_input(prompt.format(title))
    if answer.upper() == "N":
        titles_list.remove(title)

print titles_list


3 commentaires

Vous voudrez peut-être mentionner que le formatage de la chaîne de style ne fonctionne que dans Python 2.7 et ultérieurement.


C'est en fait disponible en 2,6 ou plus tard


Mais oui, si vous devez utiliser 2,5 ou antérieur, le {} dans la chaîne de format doit être remplacé par un % s et la commande de formatage lui-même devient Invient% titre .



1
votes

Je pense que le problème principal de votre code était une utilisation incorrecte de la fonction supérieure. Une fois que vous le corrigez, vous pouvez supprimer les titres de la liste comme vous le souhaitez. Vous pouvez utiliser l'index ou la valeur. Voici le code coupé qui a fonctionné pour moi xxx

Veuillez consulter les lignes commentées à l'aide de l'index. En outre, vous pouvez rendre votre code plus concis à l'aide de la fonctionnalité Raw_Input (Invite).

Vous devez également penser au scénario où il existe plusieurs occurrences des mêmes titres de votre liste, dans ce cas, je suggère. Obtenez tous les indices du titre jusqu'à ce que la liste soit vide et supprimez les titres à l'aide de Del (Index) car les solutions présentées ci-dessus suppriment uniquement la première occurrence du titre.


1 commentaires

Pas besoin d'utiliser le module String - réponse.upper () fonctionne juste bien. Cependant, avez-vous essayé cela et voyez-vous ce qui se passe lorsque vous appuyez sur n à chaque fois? Vous n'aurez aucune chance de supprimer "math" ou "it" dans la liste.



1
votes

Je sais qu'il y a déjà une réponse, voici une autre façon de complétude et de démontrer la compréhension de la liste.

Cette méthode prend une liste, demande à conserver chaque article et à renvoyer une nouvelle liste à l'exclusion des celles marquées pour la suppression. : xxx


0 commentaires