IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Parcourir une liste dans laquelle on veut supprimer des éléments


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 10
    Points
    10
    Par défaut Parcourir une liste dans laquelle on veut supprimer des éléments
    Bonjour,

    Débutant en Python, je cherche un moyen propre de faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for j in range(len(maliste)):
        if maliste[j].test()==True : 
            maliste.remove(maliste[j])
    Propre, parce que dans la mesure où je vais modifier la taille de ma liste en cours de route, il n'est évidemment pas approprié d'utiliser la taille de cette même liste dans ma boucle for.
    Est-ce qu'il existe une astuce toute bête en Python ou dois-je passer par une seconde liste ?

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Bonjour,

    Je ne comprend pas d'où vient ton attribut test()?

    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Rien à voir en fait,
    Dans la pratique il s'agit d'une liste d'objets issus d'une classe maison, pour laquelle j'ai une méthode qui s'appelle test qui renvoie un booléen.

  4. #4
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 823
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 823
    Points : 7 119
    Points
    7 119
    Par défaut
    Voir peut-etre du coté de filter qui me semble plus beau

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> def odd(n):                 1
    ...     return n % 2
    ...     
    >>> li = [1, 2, 3, 5, 9, 10, 256, -3]
    >>> filter(odd, li)             2
    [1, 3, 5, 9, -3]
    >>> [e for e in li if odd(e)]   3
    >>> filteredList = []
    >>> for n in li:                4
    ...     if odd(n):
    ...         filteredList.append(n)
    ...     
    >>> filteredList
    [1, 3, 5, 9, -3]
    source : http://python.developpez.com/cours/D...ring_lists.php
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Membre averti Avatar de alexdevl
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    265
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2007
    Messages : 265
    Points : 344
    Points
    344
    Par défaut
    Bonjour
    On peut utiliser pop ou une list comprehension mais il faut itérer sur les objets pas sur l'indice


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    class Cl:
        "Classe exemple avec un attribut"
        def __init__(self,param):
            self.at=param
     
    def lstcre():
        "Creation de la liste d'objet"
        lst=[]
        for i in range(5):
            lst.append(Cl(i))
        return lst
     
    def aff(lst):
        "Affichage de la liste d'objet"
        for cl in lst:
            print cl,cl.at
        print
     
    print "a) avec enumerate et pop"
    lst=lstcre()
    aff(lst)
    for i,l in enumerate(lst):
        if l.at in [1,3] : lst.pop(i) 
    aff(lst)
     
    print "b) avec filter"
    lst=lstcre()
    aff(lst)
    def sup13(el):
           return el.at not in [1,3]
    lst=filter(sup13,lst)
    aff(lst)
     
    print "c) Avec une list comprehension"
    lst=lstcre()
    aff(lst)
    lst=[el for el in lst if el.at not in [1,3]]
    aff(lst)

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 15
    Points : 10
    Points
    10
    Par défaut
    Merci beaucoup.
    L'astuce avec enumerate fonctionne à merveille, c'est tout à fait ce que je cherchais.

  7. #7
    Membre à l'essai
    Inscrit en
    Mai 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 19
    Points : 23
    Points
    23
    Par défaut
    Bonjour,

    je me permet de faire la remarque suivante, au lieu de
    Citation Envoyé par BnouK Voir le message
    if maliste[j].test()==True :
    il est préférable d'utiliser directement "if maliste[j].test():"

  8. #8
    Membre éclairé
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Points : 803
    Points
    803
    Par défaut
    Utilise la fonction filter() ou une compréhension de liste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # Filter
    print filter(lambda o: not o.test(), maliste)
     
    # Compréhension
    print [o for o in maliste if not o.test()]
    Tu peux réassigner le résultat dans maliste pour avoir une nouvelle liste avec seulement les éléments désirés.

  9. #9
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut Mes solutions en 4 lignes
    Le problème résidant dans le fait que, si on élimine des éléments de la liste, l'index va se trouver vers la fin du parcours de range(len(maliste)) hors de la dimension de la liste raccourcie, provoquant ainsi une erreur
    IndexError: list index out of range
    et non pas dans le fait que range(len(maliste)) verrait la valeur len(maliste)varier en cours d'exécution, ce qui n'a évidemment aucun sens puisque range(len(maliste)) utilise la valeur len(maliste) une seule fois, pour créer la liste stable range(len(maliste)) avant de rentrer dans la boucle,

    il suffit de mettre un try except pour traiter le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for j in range(len(maliste)):
        try:
            if maliste[j].test():    maliste.remove(maliste[j])
        except IndexError:    break



    On peut aussi contourner le problème en parcourant la liste de la fin vers le début:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ranj = range(len(maliste))
    ranj.reverse()
    for j in ranj:
        if maliste[j].test():    maliste.remove(maliste[j])


    Python, c'est agile et concis !

Discussions similaires

  1. parcourir une liste et supprimer des éléments selon une condition
    Par jean-pat dans le forum Général Python
    Réponses: 17
    Dernier message: 17/03/2017, 22h07
  2. Parcourir une liste dans une liste
    Par adissa357 dans le forum Général Java
    Réponses: 7
    Dernier message: 30/10/2013, 14h13
  3. [SP-2010] Parcourir une liste dans un timer Job
    Par hamzaj dans le forum SharePoint
    Réponses: 0
    Dernier message: 16/05/2011, 18h21
  4. [Batch] Parcourir une liste dans un autre fichier
    Par jepasderemy dans le forum Scripts/Batch
    Réponses: 5
    Dernier message: 22/10/2009, 09h49
  5. Réponses: 5
    Dernier message: 03/02/2004, 14h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo