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 tableaux "par colonnes" comme Excel


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Inscrit en
    Octobre 2004
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 36
    Points : 26
    Points
    26
    Par défaut Trier tableaux "par colonnes" comme Excel
    Bonjour,

    Imaginons les tableaux suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ['paul', 'homme','10']
    ['paulette', 'femme','16']
    ['paula', 'femme','10']
    ['paulo', 'homme','12']
    ['pauline', 'femme','16']
    Je voudrais faire comme la fonction Excel "trier par colonnes" et notamment : colonne 3 puis 2 puis 1 pour arriver à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ['paulette', 'femme','16']
    ['pauline', 'femme','16']
    ['paulo', 'homme','12']
    ['paul', 'homme','10']
    ['paula', 'femme','10']
    Comment faire sous Python ? Je connais la fonction sort(), bien sûr, mais je ne vois pas comment l'utiliser même en créant un gros tableaux à deux dimensions...

    Une idée ?

  2. #2
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Le code ci-dessous (fait rapidement) range les valeurs de la plus grande à la plus petite :
    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
    #! /usr/bin/env python
    #coding=utf-8
     
    def specialComparison(x, y):
        for i in range(len(x)-1, -1, -1):
            if x[i] > y[i]:
                return -1
            elif x[i] < y[i]:
                return 1
        return 0
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    listTest.sort(specialComparison)
    print repr(listTest)
    Il faut mettre 16 et non '16' pour que Python fassse une comparaison numérique.

    On obtient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [ ['pauline', 'femme', 16],
      ['paulette', 'femme', 16],
      ['paulo', 'homme', 12],
      ['paul', 'homme', 10],
      ['paula', 'femme', 10] ]

  3. #3
    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
    Bravo Rambc, très belle fonction!

    Je l'ai juste modifié en utilisant la fonction cmp() pour voir.

    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
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
     
    def specialComparison(x, y):
        for i in range(len(x)-1, -1, -1):
            a=cmp(x[i],y[i])
            return a
        return a
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    listTest.sort(specialComparison)
    listTest.reverse()
    print repr(listTest)
    Le résultat est le même bien sur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [['pauline', 'femme', 16], ['paulette', 'femme', 16], ['paulo', 'homme', 12], ['paula', 'femme', 10], ['paul', 'homme', 10]]
    Edit 1: Je me suis demandé si dans python il y avait pas quelquechose de prévu pour cela, eh bien bingo, il y a le module operator et la fonction sorted()

    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
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
     
    import operator
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    listTest=sorted(listTest, key=operator.itemgetter(2), reverse=True)
    print listTest
    Avec un résultat identique, évidemment...

    Edit 2:

    Mieux ou plus court je ne sais pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    print sorted(listTest, key=lambda x:(x[2], x[1], x[0]), reverse=True)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ['pauline', 'femme', 16]
    ['paulette', 'femme', 16]
    ['paulo', 'homme', 12]
    ['paul', 'homme', 10]
    ['paula', 'femme', 10]
    Enfin voila un panel de soluces...

    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)

  4. #4
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Une version sans for pour le plaisir :
    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
    #! /usr/bin/env python
    #coding=utf-8
     
    def specialComparison(x, y):
        if x[-1] > y[-1]:
            return -1
        elif x[-1] < y[-1]:
            return 1
        else:
            try:
                return specialComparison(x[:-1], y[:-1])
            except:
                return 0
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    listTest.sort(specialComparison)
    print repr(listTest)
    PS : fred1599 je regarderais ton code pour voir pourquoi il marche.

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    print sorted(listTest, key=lambda x:(x[2], x[1], x[0]), reverse=True)
    Cela est bien joli.

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Quelqu'un pourrait-il m'aider sur un probleme annexe. J'utilise sorted et cela fonctionne très bien.. sauf quand une case est NULL, alors la fonction renvoie une erreur.
    Plus précisément j'affiche sous forme de tableau une table de base de données MySQL et certains champs ne sont pas renseigné et cela arrivera à l'avenir. Quand c'est un champ texte, il n'y a pas de probleme mais quand cette une date, cela ne fonctionne pas.

    code:
    #recuperation de la table Subject dans all_subject
    all_subject = model.Subject.query.all()

    #trie par date de naissance qui fonctionne uniquement quand tout les sujets ont une date de naissance
    all_subject=sorted(all_subject, key=operator.attrgetter('birth_date'), reverse=True)

    Quelqu'un serait il comment ignorer les sujets qui n'ont pas de date de naissance peuvent être mis à l'écart au début de la liste ou à la fin?

  7. #7
    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
    Un truc du genre sans doute

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if date=="":
        pass
    else :
       all_subject=sorted(all_subject, key=operator.attrgetter(date), reverse=True)
    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)

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 184
    Points
    184
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sorted(listTest, key=lambda x:(x[2], x[1], x[0]), reverse=True)
    * 1000

  9. #9
    Nouveau membre du Club
    Inscrit en
    Octobre 2004
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 36
    Points : 26
    Points
    26
    Par défaut
    Boudiou ! Merci !*

    Mais j'avoue que ça dépasse complètement mes compétences :

    specialComparison attend deux arguments, et tu n'en donnes pas, et ça marche

    et puis l'histoire des return 1 et -1, je n'y comprends rien !

    Peux-tu m'éclairer ou commenter un peu ?

    Par ailleurs, comment adapter la fonction pour que l'on puisse choisir l'ordre de préférence de classement ?

    Par exemple, si je veux classer par sexe, puis par la note en colonne 3 ?

    Merci !

  10. #10
    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
    il suffit d'inverser les indices

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
     
    listTest = [
                    ['paul', 'homme', 10] ,
                    ['paulette', 'femme', 16] ,
                    ['paula', 'femme', 10] ,
                    ['paulo', 'homme', 12] ,
                    ['pauline', 'femme', 16]
               ]
     
    liste=sorted(listTest, key=lambda x:(x[1], x[2], x[0]), reverse=True)
    for listes in liste:
        print liste
    réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ['paulo', 'homme', 12]
    ['paul', 'homme', 10]
    ['pauline', 'femme', 16]
    ['paulette', 'femme', 16]
    ['paula', 'femme', 10]
    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)

  11. #11
    Nouveau membre du Club
    Inscrit en
    Octobre 2004
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 36
    Points : 26
    Points
    26
    Par défaut
    Oui, bien entendu... Mais en l'occurrence je parlais de la fonction de rambc, que je n'ai toujours pas comprise... (pardon, je n'étais pas clair).

    La tienne est limpide !

  12. #12
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par Naoli Voir le message
    specialComparison attend deux arguments, et tu n'en donnes pas, et ça marche

    et puis l'histoire des return 1 et -1, je n'y comprends rien !

    Peux-tu m'éclairer ou commenter un peu ?
    Dans listTest.sort(specialComparison), la méthode sort attend une fonction comme argument. Il faut se souvenir que Python permet de traiter les fonctions comme des variables.

    Voir cette page pour savoir comment définir une fonction de tri.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Octobre 2004
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 36
    Points : 26
    Points
    26
    Par défaut
    Super, merci bien


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

Discussions similaires

  1. trier une liste par colonnes
    Par Sniper37 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 26/10/2007, 10h19
  2. Redimentionner colonne DrawGrid comme Excel
    Par Ricquet dans le forum Delphi
    Réponses: 2
    Dernier message: 16/02/2007, 11h56
  3. [Tableaux] Tri par colonnes
    Par sfc2000 dans le forum Langage
    Réponses: 15
    Dernier message: 20/05/2006, 12h44

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