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 :

Liste avec dictionnaire, tri des clés et sélection des variables


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Apprenant Médiamaticien
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenant Médiamaticien
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Liste avec dictionnaire, tri des clés et sélection des variables
    Bonjour à vous,

    Pour commencer, je vais un peu me présenter et essayer de pas trop m'afficher. Il y a environ 4 semaines, j'ai commencé la lecture d'un livre sur les généralités de la programmation dans le cadre de ma formation de Médiamaticien . Le livre en question propose des exercices en python, j'ai donc approfondi mes connaissances grâce au tutoriel sur ce site (très beau travail d'ailleurs, merci).

    Sa fait environ une semaine que je cherche réponse à un problème proposé par un collègue.

    Problème posé :
    "Il faut analyser la valeur de la clé 'a' de tous les dicos, un dictionnaire après l'autre. Si la valeur est égal (par ex. d1['a'] == d2['a']) je continue mon programme et analyse les valeurs des clés 'b' de ces mêmes dictionnaires. Si la valeur 'b' du premier dictionnaires (d1) est supérieur à la valeur du deuxième (d2), je supprime le dictionnaire (d2) et recommence ma boucle pour comparer les autres. Si la valeur de la valeur de d2 de la clé 'b' est plus grande, je supprime le dictionnaire d1.
    Dans le cas ou les valeurs des clés 'a' ne sont pas égal, je passe directement au prochain dictionnaire et continue l'analyse en commencant toujours par la clé 'a'.

    Désolé pour cette confusion de mots et de lettres, ce sera peut-être plus évident avec mon ébauche de code...

    Python 3.2
    Je travaille avec IDLE

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    # Trois dictionnaires avec des clés similaires
    d1 = {"a":0, "b":6, "c":3, "d":12}
    d2 = {"a":1, "b":5, "c":5, "d":3}
    d3 = {"a":1, "b":6, "c":7, "d":9}
    d4 = {"a":2, "b":5, "c":7, "d":9}
    
    #Liste de mes dicos
    dicos = [d1,d2,d3,d4]
    
    #Je tri les dictionnaire en référence à la clé 'a'
    
    dicos = sorted(dicos, key=lambda k: k['a'])
    
    #Clé de référence pour 'a'
    key_a = 'a'
    #Création d'une liste temporaire pour y insérer mes valeurs pour chaque clés
    values_dico_A = []
    
    #------------------------------------------
    #Création d'une fonction qui permette l'analyse de la première condition, il faut que les valeurs de la clé 'a' 
    des deux premiers dicos soit égal pour passer à la deuxième fonction milieuFx
    
    def debutFx ():
        n,max = 0, len(dicos)
        print (dicos)
    
        for dico in dicos:
            values_dico_A.append(dico[key_a])
        print(values_dico_A)
    
        if values_dico_A[n] != values_dico_A[n+1]:
            print("1er if")
            n = n +1
    
        elif values_dico_A[n] == values_dico_A[n+1]:
            print("Passe a la deuxième fonction")
            milieuFx()
    #------------------------------------------       
    key_b = 'b'            
    values_dico_B = []
    #------------------------------------------
    #Je créer une deuxième fonction pour analyser la deuxième clé et continuer avec les autres dictionnaires // Mon soucis de compréhension débute par ici...
    
    def milieuFx ():
        for dico in dicos:
            values_dico_B.append(dico[key_b])
        print(values_dico_B)
    
        if values_dico_B[n] > values_dico_B[n +1]:
            del dicos[n+1]
            print(dicos, "deuxième if")
    
        else:
            del dicos[n]
            print(dicos, "dernière condition")
        debutFx()
    
    
    print(debutFx(), milieuFx, end= "")
    Vu que j'incrémente la variable n de 1, l'IDLE m'affiche une erreur 'out of range' que je n'arrive pas à résoudre.

    Mon but final dans l'exercide est d'avoir la clé 'a' de chaque dictionnaire avec une valeur unique et avec le plus grand score dans les autres clés. Et de pouvoir ajouter des dictionnaires dans ma liste avec les mêmes clés.

    Dans tous les cas, merci pour votre lecture et si vous arrivez à m'aiguiller dans la bonne direction se serait avec plaisir.

    Bien à vous.
    Bonne semaine

  2. #2
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Je pense que je n'ai rien compris du tout.

    Cette interéssante constatation n'empêche pas de te proposer une simplification de tes deux fonctions (par ailleurs érronnées)

    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
    40
     
    # -*- coding: utf-8 -*-
     
    d1 = {"a":0, "b":6, "c":3, "d":12}
    d2 = {"a":1, "b":5, "c":5, "d":3}
    d3 = {"a":1, "b":6, "c":7, "d":9}
    d4 = {"a":2, "b":5, "c":7, "d":9}
     
    dicos = [d1,d2,d3,d4]
     
    dicos = sorted(dicos, key=lambda k: k['a'])
     
    def debutFx():
        found = False
        for i, dc in enumerate(dicos[:-1]):
            if dc['a'] != dicos[i + 1]['a']:
                continue
     
            else:
                found = dc
                break
     
        return found
     
    def milieuFx():
        dcs = []
        for i in range(len(dicos) - 1):
            if dicos[i]['b'] > dicos[i + 1]['a']:
                dcs.append(dicos[i + 1])
     
            else:
                dcs.append(dicos[i])
     
        for dc in dcs:
            dicos.remove(dc)
     
        return dicos
     
    print(debutFx())
    print(milieuFx())
    J'obtiens ce résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    {'a': 1, 'c': 5, 'b': 5, 'd': 3}
    [{'a': 0, 'c': 3, 'b': 6, 'd': 12}]
    Est-ce ce qui était attendu ?

  3. #3
    Expert éminent

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Pour infos, j'ai commenté tes deux fonctions:
    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
     
    def debutFx ():
        n,max = 0, len(dicos)
        #print (dicos)
     
        for dico in dicos:
            values_dico_A.append(dico[key_a])
        print(values_dico_A)
     
        if values_dico_A[n] != values_dico_A[n+1]:
            print("1er if")
            n = n +1        # Ici tu incrémentes n, mais nous ne sommes pas (plus)
                            # dans une boucle ...
     
        elif values_dico_A[n] == values_dico_A[n+1]:
            print("Passe a la deuxième fonction")
            milieuFx()
    et
    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 milieuFx ():
        for dico in dicos:
            values_dico_B.append(dico[key_b])
        print(values_dico_B)
     
        if values_dico_B[n] > values_dico_B[n +1]:  # Ici n n'est pas dans l'espace
            del dicos[n+1]                          # de nom de cette fonction et
            print(dicos, "deuxième if")             # devrait lever une exception
     
        else:
            del dicos[n]
            print(dicos, "dernière condition")
        debutFx()

  4. #4
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Citation Envoyé par CandyCH Voir le message
    Mon but final dans l'exercide est d'avoir la clé 'a' de chaque dictionnaire avec une valeur unique et avec le plus grand score dans les autres clés. Et de pouvoir ajouter des dictionnaires dans ma liste avec les mêmes clés.
    je n'ai pas tout compris sur le but de la manœuvre, mais s'il s'agit simplement d'avoir un dictionnaire des valeurs maximum:

    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
    # Trois dictionnaires avec des cles similaires
    d1 = {"a":0, "b":6, "c":3, "d":12}
    d2 = {"a":1, "b":5, "c":5, "d":3}
    d3 = {"a":1, "b":6, "c":7, "d":9}
    d4 = {"a":2, "b":5, "c":7, "d":9}
     
    #Liste de mes dicos
    dicos = [d1,d2,d3,d4]
     
    # creation table des clefs
    key_list = []
    for dic in dicos:
        for key in dic.keys():
            if not key in key_list:
                key_list.append(key)
    key_list.sort()
     
    # analyse proprement dite
    result_dico = {}
    for key in key_list:
        max = 0
        for dic in dicos:
            if key in dic.keys():
                value = dic[key]
                if value > max:
                    max = value
        result_dico[key] = max
     
    #affichage resultats
    for key in key_list:
        print(key, result_dico[key])
    A+

    Pfeuh

  5. #5
    Candidat au Club
    Homme Profil pro
    Apprenant Médiamaticien
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenant Médiamaticien
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Salut à vous,

    En tout cas merci, je vois qu'il y a encore du boulot et pas que pour la programmation.

    Je vais essayer de reformulé le but de mon exercice :

    J'ai un nombre de dictionnaire dans une liste (c'est la seule solution que j'ai trouvé pour comparer les valeurs dans les clés de chaque dictionnaire).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    d1 = {"a":0, "b":6, "c":3, "d":12}
    d2 = {"a":1, "b":5, "c":5, "d":3}
    d3 = {"a":1, "b":6, "c":7, "d":9}
    d4 = {"a":2, "b":5, "c":7, "d":9}
     
    dicos = [d1,d2,d3,d4]

    Il faut analyser la valeur de la clé 'a' de d1 et la comparé avec la valeur de la même clé de d2.

    Si la valeur dans d1['a'] (0) n'est pas égale à la valeur de d2['a'] (1), dans ce cas je garde le dictionnaire d1 et procède de la même manière avec d2 et d3.

    Dans ce cas vu que 0 (d1) et 1 (d2) ne sont pas égales, je garde donc d1 dans ma liste dicos=[] et continue avec le dictionnaire d2.

    Dans d2['a'] (1) et d3['a'] (1) les valeurs sont égales, je reste dans ces deux dictionnaires et je vais regarder lequel à le nombre le plus élevé dans la clé 'b' . Dans ce cas d3['b'] (6) > que d2['b'] (5) donc je supprime dans ma liste le dictionnaire avec le nombre le plus petit, le dictionnaire d2.

    Après avoir éloigné le dictionnaire d2 de ma liste dicos, je continue avec d3 avec la même logique.

    Ce n’est pas très brillant, mais j'espère que sa vous fait pas souffrir les neurones.

  6. #6
    Candidat au Club
    Homme Profil pro
    Apprenant Médiamaticien
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenant Médiamaticien
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Enfaite ce n’est pas le premier ce bout de code n'est pas mon premier essai. J'ai essayé avec while, for, for dans la boucle while...

    Tout ça pour dire que ce n’est pas une obligation d'utiliser les fonctions, j'ai pensé que ça pouvait m'aider.

    Dès que je serais chez moi j'enverrai l'algorithme du programme.

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

    Ta description du problème est plutôt une ébauche de solution (un algorithme); cela vaudrait la peine de "s'élever" un peu et de décrire le problème de façon plus déclarative.

    Voilà ce que j'ai pu reconstituer: tu disposes de plusieurs dictionnaires, qui ont tous au moins une clé "a" et une clé "b" et tu désires n'en garder qu'un seul pour chaque valeur distincte de la clé "a", en l’occurrence celui qui possède la plus grande valeur pour la clé "b". C'est bien ça ? Ce que tu ne dis pas, il me semble, c'est ce qui doit se passer si les valeurs pour les clés "b" sont égales; j'ai donc supposé que l'on en gardait un seul, mais choisi arbitrairement.

    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
    from itertools import groupby
    from pprint import pprint
     
    d1 = {"a":0, "b":6, "c":3, "d":12}
    d2 = {"a":1, "b":5, "c":5, "d":3}
    d3 = {"a":1, "b":6, "c":7, "d":9}
    d4 = {"a":2, "b":5, "c":7, "d":9} 
    dicos = [d1,d2,d3,d4]
     
    # tri suivant clé 'a'
    dicos = sorted(dicos, key=lambda k: k['a'])
    # regrouper sur les valeurs de la clé 'a'
    groups = [list(g) for k,g in groupby(dicos, key=lambda k: k['a'])]
    # ne garder que le plus grand résulat de chaque groupe, d'après la clé 'b'
    result = [max(g, key=lambda k: k['b']) for g in groups]
     
    pprint(result)
    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [{'a': 0, 'b': 6, 'c': 3, 'd': 12},
     {'a': 1, 'b': 6, 'c': 7, 'd': 9},
     {'a': 2, 'b': 5, 'c': 7, 'd': 9}]

  8. #8
    Candidat au Club
    Homme Profil pro
    Apprenant Médiamaticien
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenant Médiamaticien
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Salut dividee,

    Ben t'as tout compris et le résultat que tu te proposes était la solution que je cherchais.

    Cela étant, je crois tout de même que là on est passé un cran au dessus de ce que je suis capable de faire et comprendre. Je vais essayé de raisonner sur ta solution et comprendre comment ça fonctionne.

    Est-ce que c'est possible de garder ce sujet ouvert pour poser des questions relatives à la solution proposé ?

    Un remerciement banal, mais très sincère à vous tous.

  9. #9
    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
    Bonsoir,

    Comme tu utilisais déjà sorted, je ne pense pas que cette ligne te pose problème. Et si tu as compris sorted, avec l'argument "key", max est à ta portée également.

    Il reste deux difficultés:
    * Les lists comprehensions [... for ... in ...]. Comme tu n'en utilisais pas dans ton code initial, tu n'es peut-être pas familier avec celles-ci. Prends un peu de temps et expérimente pour les comprendre, ce n'est pas bien compliqué et c'est vraiment une fonctionnalité très utile de Python.

    * groupby. C'est une fonction du module itertools qui un peu complexe de prime abord.
    En la simplifiant un peu, on pourrait la coder comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def groupby(l, key):
        groups = []
        group = []
        val = key(l[0])
        for e in l:
            if key(e) == val:
                group.append(e)   # tant que la clé est identique, ajouter à group
            else:                           # lorsque la clé diffère:
                groups.append((val, group)) # ajouter sa valeur et le groupe au résultat
                val = key(e)                # sauver la nouvelle valeur de la clé
                group = [e]                 # commencer un nouveau groupe avec cet élément
        groups.append((val, group))     # ajouter le dernier groupe
        return groups
    (ce qui rend la fonction de itertools un peu plus complexe, c'est l'utilisation des itérateurs au lieu des listes, mais sinon le résultat est le même).

    Un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> groupby([1,1,1,2,3,3,4,4,1,1,5], key=lambda x:x)
    [(1, [1, 1, 1]), (2, [2]), (3, [3, 3]), (4, [4, 4]), (1, [1, 1]), (5, [5])]
    groupby regroupe les éléments sur la valeur de la clé (la liste doit déjà être triée au préalable), elle retourne une liste de groupes, chaque groupe étant un tuple de 2 éléments: la valeur de la clé pour ce groupe, suivi des éléments qui appartiennent au groupe.

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

Discussions similaires

  1. Tri d'une HashMap à partir des clés
    Par Eithne dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 15/06/2011, 16h40
  2. Réponses: 6
    Dernier message: 08/11/2008, 15h37
  3. Réponses: 2
    Dernier message: 02/02/2008, 19h04
  4. Réponses: 12
    Dernier message: 12/03/2007, 16h58
  5. sélection des bd en fonction des utilisateurs (pg_hba.conf)
    Par Bouboubou dans le forum PostgreSQL
    Réponses: 9
    Dernier message: 18/03/2004, 18h34

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