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 :

Treeview à partir d'une liste


Sujet :

Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Treeview à partir d'une liste
    Bonjour,

    Je débute avec Python (important de le préciser ) et je bloque souvent sur le même problème, sans trouver une solution propre.

    J'aimerai réaliser un listing d'objets type Treeview (ou arbre généalogique ) à partir de données allant de paire.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maListe = [["orange","fruit"], ["banane","fruit"], ["courgette", "legume"], ["chaise", "meuble"]]
    Ce qu'il me faudrait comme résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maNouvelleListe = [[fruit, [orange, banane]], [legume, [courgette]], [meuble,[chaise]]
    Si vous aviez quelques pistes d'idées cela m'aiderait beaucoup
    Merci par avance

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Je dirais 3 solutions

    - Les dictionnaires
    - Les namedtuple
    - Les classes

    Si tu es débutant je te conseille les dictionnaires, mais le problème c'est que je ne sais pas ce que tu veux en faire après.

    Sinon j'aime bien les classes mais pour ton niveau (à moins que tu connaisses d'autres langages) c'est un peu trop évolué.

    Edit : Ce qui donnerait en faisant simple

    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
    maListe = [["orange","fruit"], ["banane","fruit"], 
              ["courgette", "legume"], ["chaise", "meuble"]]
     
    dico = {}
     
    for liste in maListe:
        value, key = liste
        if key not in dico:
            dico[key] = [value]
        else:
            dico[key].append(value)
     
    print dico
     
    # {'legume': ['courgette'], 'fruit': ['orange', 'banane'], 'meuble': ['chaise']}
     
    # Dictionnaire trié
     
    dico = OrderedDict(sorted(dico.items(), key=lambda t: t[0]))
     
    # OrderedDict([('fruit', ['orange', 'banane']), ('legume', ['courgette']), ('meuble', ['chaise'])])
    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
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Merci de ta réponse

    Alors je me suis rendu compte de quelques problèmes.

    D'une part j'ai oublié de préciser que ma version de Python est la 2.6
    Je travail en effet sur Maya un logiciel d'infographie 3D.

    Et donc d'après mes quelques recherches OrderedDict() n'est disponible qu'à partir de la 2.7 ...

    Deuxièmement je ne sais pas si mon exemple était le meilleur.

    En gros ma liste initiale est agencée de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    exempleList = [["Parent1","Child1"], ["Parent1","Child2"], ["Child1","Child3"], ["Parent2","Parent1"]]
    De manière visuelle j'obtient quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Parent2
    |-Parent1
    |---Child1
    |-----Child3
    |---Child2
    En gros chaque liste peut contenir plusieurs listes qui elles même en contiennent d'autres etc ... Un tableau en somme.
    J'ai fait quelques tests, seulement je me retrouve à faire des boucle dans des boucles dans des boucles etc ... Au final je cherche simplement à trier un liste.

    Voilà j'espère avoir était assez explicite, j'avoue que c'est un peu compliqué pour moi :') Merci encore

  4. #4
    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,

    Ça, c'est un problème amusant!

    Et assez général: construire un arbre des descendances à partir de liens de filiations. C'est un problème qu'on rencontre aussi dans la construction des graphes de planification à partir des liens de précédences des tâches.

    Voilà comment je ferais.

    0- rappel des données: la liste des liens de filiation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    d = [["Parent1","Child1"], ["Parent1","Child2"], ["Child1","Child3"], ["Parent2","Parent1"]]
    1- il faut trouver le début de l'arbre, c'est à dire le ou les parent(s) jamais cité(s) comme enfant dans les liens de filiation:

    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 cherche_parents_initiaux(d):
        """cherche le ou les parent(s) sans ascendance """
        a = []
        for p1, c1 in d:
            sansparent = True
            for p2, c2 in d:
                if p1 == c2:
                    # ici, le parent p1 est cité comme enfant c2
                    sansparent = False
                    break
            if sansparent:
                # ici: p1 = parent jamais cité comme enfant dans les filiations
                a.append(p1)    
        return a
    2- Pour chaque parent sans ascendance, il faut trouver ses enfants, puis les enfants de ses enfants, etc... Pour cela, on va construire l'arbre des descendances comme une liste de listes en choisissant comme 'brique' de base: [parent, [enfant1, enfant2, ...]]. Chaque enfant pouvant, bien entendu, reprendre la même 'brique': [enfant1, [enfants1_1, enfant1_2, ...]]. Les 'feuilles' de l'arbre sont représentées par les enfants sans descendances: [enfant, []].

    On note que l'algorithme de construction de l'arbre sera logiquement récursif, en espérant ici qu'on ne dépassera pas la pile de récursion limitée chez Python (env. 1000). Si l'arbre devait être trop complexe, il faudrait faire une version non récursive.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def cherche_enfants(p, d):
        """cherche les enfants de p dans la liste des filiations d """
        l = [p, []]
        for p1, c1 in d:
            if p == p1:
                l[1].append(cherche_enfants(c1, d))
        return l
    3- Il ne reste plus qu'à créer une fonction d'affichage, parce que le simple affichage de l'arbre est difficilement exploitable visuellement (trop compliqué):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def affiche_arbre(a, niv=0):
        """affiche l'arbre des descendances a """
        if a!=[]:
            print "=="*niv + a[0]
            for e in a[1]:
               affiche_arbre(e, niv+1)
    Voilà comment on exploite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # recherche du ou des parents sans ascendance
    a = cherche_parents_initiaux(d)
     
    # pour chacun de ces parents, construction de l'arbre des descendances
    for p in a:
        arbre = cherche_enfants(p, d)
        affiche_arbre(arbre)
        print
        print arbre
    Ce qui affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Parent2
    ==Parent1
    ====Child1
    ======Child3
    ====Child2
     
    ['Parent2', [['Parent1', [['Child1', [['Child3', []]]], ['Child2', []]]]]]
    Dans le cas général, il faudrait tester les cas de boucles de l'arbre pour éviter les plantages. Dans les arbres généalogiques, ça doit être plutôt rare (un enfant ne peut pas être son propre grand-père), mais dans les graphes de planifications, ça arrive (2 tâches qui s'attendent l'une l'autre).

    Je n'ai pas testé dans tout les cas, mais le principe est là: bon courage!
    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

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Et bien tout d'abord merci pour cette réponse exhaustive
    Il va me falloir un peu de temps pour tout comprendre mais le résultat est bien la ! Tout fonctionne parfaitement
    En ce qui concerne les éventuelles boucles, ne vous en faites pas, chaque objet ne peut avoir qu'un seul parent dans mon cas

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

Discussions similaires

  1. Nouveau "recordset" a partir d'une liste !!!
    Par AngelsGuardian dans le forum Access
    Réponses: 1
    Dernier message: 01/11/2005, 20h46
  2. Réponses: 32
    Dernier message: 22/09/2005, 10h40
  3. Réponses: 3
    Dernier message: 19/05/2005, 17h52
  4. Réponses: 3
    Dernier message: 25/04/2005, 15h26
  5. Trouver equation à partir d'une liste de points
    Par scarabee dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 27/05/2004, 17h05

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