Partage
  • Partager sur Facebook
  • Partager sur Twitter

construire dictionnaire à partir de 3 listes

Sujet résolu
    5 mars 2016 à 17:01:47

    Bonjour, pourriez-vous me dire comment je dois formuler le "slicing" de new_list? Faute de mieux, j'ai fait :

    new_list=res[0:3], res[3:6], res[6:9], res[9:12]

    ce qui est valable pour le cas particulier étudié ici, mais n'est pas valable pour un cas général. J'ai pensé à faire :

    new_list=res[0:int(len(res))//3-1]

    mais cela ne donne rien. Mon script fonctionne bien pour ce cas précis, il me donne le bon résultat, je pense que le seul problème réside dans cette ligne.

    Il faut écrire une fonction qui accepte 3 listes à 1 dimension et construit et retourne un dictionnaire comme spécifié ci-dessous:

    - la première liste à 1 dimension a "n" strings qui sont des noms de personnes.

    -  la seconde liste à 1 dimension a "n" entiers qui sont les âges correspondant à ces personnes

    -  la troisième liste à 1 dimension a "n" entiers qui sont les notes obtenues par ces personnes. Si une personne a 60 ou davantage, elle a réussi l'examen (mention "pass") et sinon elle a échoué (mention "fail").

    Votre fonction doit retourner un dictionnaire où chaque clé est le nom d'une personne et la valeur correspondant à cette clé est une liste contenant l'âge, la note et la mention "pass" ou "fail" dans le même ordre que dans l'exemple. 

    Par exemple, si la fonction reçoit les listes suivantes :

    (["paul", "saul", "steve", "chimpy"], [28, 59, 22, 5], [59, 85, 55, 60])

    elle doit retourner le dictionnaire ci-dessous. L'ordre des clés dans le dictionnaire n'est pas forcément le même que dans l'exemple.

    {'steve': [22, 55, 'fail'], 'saul': [59, 85, 'pass'], 'paul': [28, 59, 'fail'], 'chimpy': [5, 60, 'pass']}
    def construct_dictionary_from_lists(list1, list2, list3):
        list1 = ["paul", "saul", "steve", "chimpy"]
        list2 = [28, 59, 22, 5]
        list3 = [59, 85, 55, 60]
        list4 = []
        for i in range(0, len(list3)):   
            if list3[i]>=60:       
                list4.append('pass')
            if list3[i]<60:           
                list4.append('fail')
    
    
        res = []
        for i in range(0, len(list1)):   
            res += [list2[i], list3[i],list4[i]]
            res.append   
    
        new_list=res[0:3], res[3:6], res[6:9], res[9:12]
    
    
        keys = list1
        values = new_list 
        dictionary = dict(zip(keys, values))
        print (dictionary)
    
    list1 = ["paul", "saul", "steve", "chimpy"]
    list2 = [28, 59, 22, 5]
    list3 = [59, 85, 55, 60]
    D = construct_dictionary_from_lists(list1, list2, list3)
    print (D)

    • Partager sur Facebook
    • Partager sur Twitter
      5 mars 2016 à 17:08:52

      Salut !

      Tu peux utiliser la fonction zip():

      nom=["paul", "saul", "steve", "chimpy"]
      age=[28, 59, 22, 5]
      note=[59, 85, 55, 60]
      
      result=dict()
      
      for i,j,k in zip(nom,age,note):
      	if k >= 60:
      		result[i]=[j, k, 'pass']
      	else:
      		result[i]=[j, k, 'fail']
      
      
      print(result)



      • Partager sur Facebook
      • Partager sur Twitter
        5 mars 2016 à 20:41:04

        Merci, HSystem, ton code fonctionne parfaitement, mais uniquement dans ce cas particulier avec 4 personnes. Moi je cherche le cas général avec "n" personnes, et il me semble -sauf si je me trompe- que mon code fonctionnerait parfaitement (cela reste à vérifier) si je savais comment exprimer le "slicing" que j'utilise à ma ligne 18 et qui est valable seulement pour 4 personnes car je ne sais pas comment le formuler pour "n" personnes.

        A la fin de la 1ère partie de mon programme (jusqu'à la ligne 10, j'obtiens : list4 = ['fail', 'pass', 'fail', 'pass']

        A la ligne 16, j'obtiens une liste à 1 dimension :

        [28, 59, 'fail', 59, 85, 'pass', 22, 55, 'fail', 5, 60, 'pass']

        et ensuite, j'essaie d'obtenir cette liste à 2 dimensions :

        [28, 59, 'fail'], [59, 85, 'pass'], [22, 55, 'fail'],[5, 60, 'pass']]

        qui me servira de "valeurs" pour construire le dictionnaire. C'est uniquement la ligne 18 qui me manque, je voudrais faire le slicing pour obtenir dans chaque sous-liste l'âge, la note et la mention "pass" ou "fail".

        -
        Edité par Anpiet 5 mars 2016 à 21:12:05

        • Partager sur Facebook
        • Partager sur Twitter
          6 mars 2016 à 10:32:58

          Je suis pas sûr de bien comprendre,

          A partir du moment où tu as le même nombre d'éléments dans chaque liste, il marche avec autant de personnes que tu veux.

          Pour ta liste à deux dimensions:

          nom=["paul", "saul", "steve", "chimpy"]
          age=[28, 59, 22, 5]
          note=[59, 85, 55, 60]
           
          result=[]
           
          for i,j,k in zip(nom,age,note):
              if k >= 60:
                  result.append([j, k, 'pass'])
              else:
                  result.append([j, k, 'fail'])
           
           
          print(result)

          Je comprend vraiment pas pourquoi ça ne marcherait pas avec 5,6,7, ....n personnes.

          • Partager sur Facebook
          • Partager sur Twitter
            6 mars 2016 à 11:19:55

            HSystem t'a donné la bonne solution. Mais tu ne sembles pas en vouloir.

            Anpiet a écrit:

            si je savais comment exprimer le "slicing" que j'utilise à ma ligne 18 et qui est valable seulement pour 4 personnes car je ne sais pas comment le formuler pour "n" personnes.

            Ton slicing a la forme : 0:3, 3:6, 6:9, 9:12 ... et tu ne vois pas ce qui viendrait derrière cette suite ? ;)

            • Partager sur Facebook
            • Partager sur Twitter
              6 mars 2016 à 12:28:56

              Anpiet a écrit:

              Moi je cherche le cas général avec "n" personnes, et il me semble -sauf si je me trompe- que mon code fonctionnerait parfaitement (cela reste à vérifier) si je savais comment exprimer le "slicing" que j'utilise à ma ligne 18 et qui est valable seulement pour 4 personnes car je ne sais pas comment le formuler pour "n" personnes.


              Il suffit de découper votre séquence par paquets de 3.

              >>> s = '123' * 5>>> s
              '123123123123123'
              >>> for x in range(0, len(s), 3):
              ...     print(s[x:x+3])
              
              123
              123
              123
              123
              123
              >>>

              Mais pour un programmeur Python, zip est la fonction à laquelle il faut penser dans ce cas:

              >>> nom=["paul", "saul", "steve", "chimpy"]
              >>> age=[28, 59, 22, 5]
              >>> note=[59, 85, 55, 60]
              >>> list(zip(nom, age, note, [ n >= 60 for n in note ]))
              [('paul', 28, 59, False), ('saul', 59, 85, True), ('steve', 22, 55, False), ('ch
              impy', 5, 60, True)]
              >>> { k: v for k, *v in zip(nom, age, note, [ n >= 60 for n in note ]) }
              {'paul': [28, 59, False], 'saul': [59, 85, True], 'chimpy': [5, 60, True], 'steve': [22, 55, False]}




              • Partager sur Facebook
              • Partager sur Twitter
                6 mars 2016 à 13:34:56

                Merci beaucoup, mps, pour votre message. C'est bien cette ligne que je cherchais tellement : 

                forinrange(0len(s), 3):

                et qui semble ridiculement simple, au point de me demander si j'ai un minimum d'intelligence et si je ne devrais pas laisser tomber la programmation.Je n'ai malheureusement plus le temps de finaliser correctement mon code, car je suis en porte d'embarquement pour une semaine de vacances.

                Merci aussi à HSystem et Dan737, désolée de ne pas avoir bien saisi votre message.

                • Partager sur Facebook
                • Partager sur Twitter
                  6 mars 2016 à 13:43:16

                  Anpiet a écrit:

                  Merci beaucoup, mps, pour votre message. C'est bien cette ligne que je cherchais tellement : for x in range(0, len(s), 3):

                  Non, ce que tu cherchais était la solution à base de zip. Tes 3 listes sont indépendantes à la base, il n'y a donc aucune utilité à les fusionner pour les reséparer.

                  Et pour revenir sur ce for et ce slicing assez peu élégants, on préférera la recette grouper définie dans la documentation du module itertools : https://docs.python.org/3/library/itertools.html#itertools-recipes (mais une fois de plus, la bonne réponse à ton problème est un simple zip).

                  • Partager sur Facebook
                  • Partager sur Twitter

                  construire dictionnaire à partir de 3 listes

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown