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 :

Trier une liste d'instance avec sort()


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 82
    Points : 36
    Points
    36
    Par défaut Trier une liste d'instance avec sort()
    Bonjour,
    j'ai un petit problème de compréhention sur l'utilisation de la fonction sort() pour trier une liste.
    du genre : Liste.sort() par exemple.
    Liste contient des instances du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Cellule():
        def __init__(self, Coord, Altitude):
            self.x, self.y = Coord
            self.z = Altitude
    j'ai donc la liste suivante composée d'instance de Cellule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Liste = [a, b, c, d, e, ....]
    je souhaite trier cette liste en fonction de z... de la plus petite altitude à la plus grande.
    Dans un premier temps, j'ignore si cela est possible ^^
    Dans un second temps, l'aide en ligne du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s.sort([cmp[, key[, reverse]]])
    est pour moi un insondable mystère.
    Est ce que quelqu'un peut m'expliquer comment faire, SiyOuplait ?
    Merci d'avance.

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 298
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 298
    Points : 6 778
    Points
    6 778
    Par défaut
    La liste que tu donnes est une simple liste donc .sort() est suffisant

    ex:
    >>> l = [12, 56, 27.6, 91, 2, 45.5]
    >>> l.sort()
    >>> l
    [2, 12, 27.600000000000001, 45.5, 56, 91]
    >>> l.reverse()
    >>> l
    [91, 56, 45.5, 27.600000000000001, 12, 2]
    ! sort() et reverse() modifie la list 'en place et retournent None
    >>> l.sort().reverse()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'reverse'
    Est-ce-que ta liste ne serait pas plutôt du genre

    [[x, y, z], [x, y, z], [x, y, z]]
    avec z pour l'altitude, la clé de cmp est l[2]

    Edit: Il y a un How To ici: http://docs.python.org/howto/sorting.html?highlight=cmp

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà un 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
    15
    16
    17
     
    class Cellule():
        def __init__(self, Coord, Altitude):
            self.x, self.y = Coord
            self.z = Altitude
     
    a = Cellule((4,3),5)
    b = Cellule((1,2),7)
    c = Cellule((4,6),3)
    d = Cellule((8,2),4)
     
    liste = [a,b,c,d]
     
    liste.sort(key=lambda v: v.y)
     
    for inst in liste:
        print inst.x, inst.y, inst.z
    Ce qui affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1 2 7
    8 2 4
    4 3 5
    4 6 3
    On voit bien que les instances sont effectivement triées selon la coordonnée y

    A noter que sort ne change pas l'ordre des données égales: les instances b et d ne sont pas inversées.

    Le principe est simple: le "key=lambda v: v.y" dit simplement: pour les comparaisons, au lieu de l'élément v de la liste, prendre v.y.

    Il vaut mieux utiliser key que cmp, parce que cmp a disparu de Python 3.x (même si on peut le reconstituer).

    Au lieu de sort() qui trie la liste 'sur place', on peut prendre sorted() qui renvoie la liste triée sans la modifier.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    Une autre manière de voir les choses est de dire que la manière de trier une liste d'instance de Cellule est une propriété de Cellule, et que c'est donc la classe qui doit porter elle même la manière de comparer des instances entre elles.
    Celà peut se faire en définissant la méthode spéciale __cmp__() http://docs.python.org/reference/dat...object.__cmp__

    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
     
    >>> class Cellule():
    ...     def __init__(self, Coord, Altitude):
    ...             self.x, self.y = Coord
    ...             self.z = Altitude
    ...     def __cmp__(self, other):
    ...             return cmp(self.y, other.y)
    ... 
    >>> a = Cellule((4,3),5)
    >>> b = Cellule((1,2),7)
    >>> c = Cellule((4,6),3)
    >>> d = Cellule((8,2),4)
    >>> liste = [a,b,c,d]
    >>> liste.sort()
    >>> for inst in liste:
    ...     print inst.x, inst.y, inst.z
    ... 
    1 2 7
    8 2 4
    4 3 5
    4 6 3
    Cela dépend de ta conception : soit tu dis que c'est à celui qui trie de choisir la façon de trier les Cellules, soit ce sont les cellules qui savent de quelle manière elles doivent être triées.

    edit
    oups:
    Citation Envoyé par tyrtamos
    Il vaut mieux utiliser key que cmp, parce que cmp a disparu de Python 3.x (même si on peut le reconstituer).
    Je ne savais pas.
    Comment surcharger simplement les comparaisons alors (sans avoir à redéfinir tous les opérateurs un par un) dans python 3 ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 82
    Points : 36
    Points
    36
    Par défaut
    Super ^^
    Merci de vos réponses.
    J'ai le luxe de pouvoir choisir une methode pour le prix de 2 avec exemples à la clée...
    Et en plus, je découvre une astuce élégante d'utilisation des class (enfin... pour moi ^^) Merci valAa
    Merci beaucoup

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par valAa Voir le message
    Comment surcharger simplement les comparaisons alors (sans avoir à redéfinir tous les opérateurs un par un) dans python 3 ?
    C'est dans la doc de sort => http://docs.python.org/howto/sorting...-cmp-parameter

    Et pour Python v 2.7, il a été ajouté .cmp_to_key(func) dans le module functools => http://docs.python.org/library/funct...dule-functools.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    Merci tyrtamos.
    J'y lis également:
    The sort routines are guaranteed to use __lt__() when making comparisons between two objects. So, it is easy to add a standard sort order to a class by defining an __lt__() method:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> Student.__lt__ = lambda self, other: self.age < other.age
    >>> sorted(student_objects)
    [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
    Donc si j'ai bien compris la surcharge de __lt__ (operateur '<') sur une classe suffit pour définir l'ordre de tri des instances.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Citation Envoyé par valAa Voir le message
    Donc si j'ai bien compris la surcharge de __lt__ (operateur '<') sur une classe suffit pour définir l'ordre de tri des instances.
    Effectivement; le décorateur de classe total_ordering (http://docs.python.org/dev/py3k/libr...total_ordering) est aussi intéressant.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Trier une liste avec Collections.sort(liste)
    Par nakry dans le forum Collection et Stream
    Réponses: 18
    Dernier message: 25/09/2013, 16h52
  2. [XSLT] trier une liste avec une variable
    Par ieuthm dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 22/04/2008, 22h56
  3. la fonction sort pour trier une liste
    Par memo07 dans le forum C++Builder
    Réponses: 3
    Dernier message: 25/11/2007, 17h58
  4. STL Problème avec une liste d'instances de class
    Par BruceBoc dans le forum SL & STL
    Réponses: 12
    Dernier message: 16/02/2007, 15h12

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