Python créer des listes avec itérations par boucles - Page 2

Résolu
Précédent
  • 1
  • 2
  1. Thomasdu33
     
    Moi si j'ai bien compris aussi,
    - Je pense que la boucle for sert juste à envoyer un nombre dans la boucle while.

    - Après qu'avec la boucle while, cela nous donne plusieurs nombre que l'on doit trier.

    - Ensuite il nous faudrait un compteur pour savoir combien d'itérations (nombre de boucles pour moi), on a eu pour chaque boucle de for.

    Je ne sais pas si j'ai était clair.
    Après je pense que c'est Whismeril qui s'approche le plus de ce que je veux faire. Même si je comprend pas trop quand il met des coucous car je ne vois pas les différences de nombre de coucous pour chaque chiffre du range.
    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      C'est très clair. Et effectivement, Whismeril te guide correctement pour atteindre cet objectif. Si tu regardes mon message #33, tu verras comment compter le nombre de fois où tu itères sur une boucle
      while
      , ce qui donne :

      def f():
          i = 0
          for x in range(3, 4):
              print("entier : ", x)
      
              x_original = x        
              i = 0
              while x != 1: 
                  print("coucou")
                  if x % 2 == 1: 
                      x = x * 3 + 1 
                  else:   
                      x = x / 2 
                  i += 1
                  print("x: {x}", x)
              print(f"Pour la valeur {x_original} il y a eu {i} itérations")
              yield x
              
      print("max: ", max(f))


      Note que j'ai introduit
      x_original
      car tu modifies la valeur de x dans ta boucle
      while
      , et donc
      x
      vaut toujours
      1
      une fois qu'on en sort, qu'elle qu'ait été sa valeur initiale...

      Bonne chance
      0
      1. Utilisateur anonyme > mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention  
         
        Et oui, c’est pour ça que je voulais lire que Thomas voyait écrit x = 1 à la fin et pas 3, et aussi y’a plein de coucou alors que i ne vaut 1.
        Mais bon
        0
  2. Thomasdu33
     
    Bonjour,

    J'ai fais ça pour ma première liste:

    def f():
        i = 0
        for x in range(2, 5):
            print("entier : ", x)
            x_original = x
            list = []
            i = 0
            while x != 1: 
                if x % 2 == 1: 
                    x = x * 3 + 1 
                else:   
                    x = x / 2 
                i = i + 1  
                list.append(x)
                print(x) 
            yield x
            print(sorted(list, reverse = True))
            print(f"Pour la valeur {x_original} il y a eu {i} itérations")
    print(max(f()))


    Et maintenant, je dois créer une deuxième liste qui récupérera le plus grand nombre atteint pour chaque itération et la fonction max() n'est pas ce dont j'ai besoin
    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      Si j'ai bien compris ce que tu veux faire, ta boucle
      for x in range(2, 5)
      devrait être à l'extérieur de la fonction
      f
      , et f devrait prendre x en paramètre. Ainsi tu aurais au final quelque chose du genre

      def f(x):
          print(f"entier : {x}")
          #... suite de ta fonction
      
      for x in range(2, 5):
          print(f"max(f({x}) = {max(f(x)}")


      Bonne chance
      0
    2. Thomasdu33 > mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention  
       
      tu pourrais m'expliquer le fonctionnement des accolades dans le dernier print stp
      car quand j'intègre le code à mon code, ça marche pas
      0
    3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940 > Thomasdu33
       
      Dans une f-string, tout ce qui est entre accolade est évalué comme du code normal, puis le résultat est injecté dans la chaîne qu'on est en train de formater. Ainsi écrire
      "{x}"
      dans une f-string signifie "écrit la valeur de x", et écrire
      "{max(f(x))}"
      signifie "calcule max(f(x)) et met cette valeur dans la chaîne.

      Chez moi ça a l'air de marcher :

      def f(x):
          print("entier : ", x)
          x_original = x
          list = []
          i = 0    
          while x != 1:
              if x % 2 == 1:
                  x = x * 3 + 1
              else:    
                  x = x / 2
              i = i + 1
              list.append(x)
              print(x) 
          yield x  
          print(sorted(list, reverse = True)) 
          print(f"Pour la valeur {x_original} il y a eu {i} itérations")
      
      for x in range(2, 5):
          print(f"max(f({x})) = {max(f(x))}")
      

      ... donne :
      entier :  2
      1.0
      [1.0]
      Pour la valeur 2 il y a eu 1 itérations
      max(f(2)) = 1.0
      entier : 3
      10
      5.0
      16.0
      8.0
      4.0
      2.0
      1.0
      [16.0, 10, 8.0, 5.0, 4.0, 2.0, 1.0]
      Pour la valeur 3 il y a eu 7 itérations
      max(f(3)) = 1.0
      entier : 4
      2.0
      1.0
      [2.0, 1.0]
      Pour la valeur 4 il y a eu 2 itérations
      max(f(4)) = 1.0
      0
    4. Utilisateur anonyme > mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention  
       
      Bonsoir, je n'ai pas l'impression que cela réponde à l'énoncé et que ça n'est pas encore du niveau de Thomas
      0
    5. Thomasdu33 > Utilisateur anonyme
       
      Bonjour, c'est presque ça mais il me faudrait récupérer les valeurs max pour les trier en décroissant.

      J'essais de trouver un moyen de stocker et comparer les valeurs entre elles pour ensuite les mettre dans une nouvelle liste.
      0
  3. Utilisateur anonyme
     
    Bonjour

    dans ton tout premier message tu as écrit
    Je dois modifier ce programme pour afficher 2 listes après la boucle.


    Est ce que cela veut dire, que le programme t'a été donné te quel ou que c'est toi qui l'avait écrit?

    S'il t'avait été donné tel quel, je ne pense pas que tu aies "le droit" de sortir la boucle for (d"ailleurs au début c'était 2, 10 pas 2, 5).

    Quoiqu'il en soit pour répondre à l'énoncé initial, je pense que les 2 listes doivent être crées dans def et peut-être même que chacune associe la valeur du for à son résultat.

    Reprenons ton code de ce matin
    def f():
        i = 0 #cette ligne est obsolète car, comme tu l'as fait, il faut remettre i à 0 dans le while
        for x in range(2, 5): #ici, il faudra passer à 10
            print("entier : ", x)
            x_original = x
            list = [] #évite d'appeler une variable avec un mot clé du langage
            i = 0
            while x != 1: 
                if x % 2 == 1: 
                    x = x * 3 + 1 
                else:   
                    x = x / 2 
                i = i + 1  
                list.append(x)
                print(x) #ce print sert au débug, à la fin, il faudra l'enlever
            yield x 
            print(sorted(list, reverse = True)) #idem pour ce print
            print(f"Pour la valeur {x_original} il y a eu {i} itérations") #ideme pour ce print
    print(max(f()))


    Une solution (il y en a d'autres) est de créer une liste res (pour resultat) qui contiendra pour chaque valeur du for, la valeur initiale de x, puis chacune de valeurs prises par x dans la boucle while.

    Je te montre ce que ça donne
    def f():
        res = []
        for x in range(2, 10):
        
            lesX = []
            lesX.append(x)
            
            while x != 1: 
                if x % 2 == 1: 
                    x = x * 3 + 1 
                else:   
                    x = x / 2 
    
                lesX.append(x)
            res.append(lesX)
        return res
    
    
    print(f())


    A partir de ça tu pourras obtenir ce que tu souhaites.

    0
    1. Thomasdu33
       
      Le problème avec le deuxième c'est qu'on ne voit pas le compteur d'itérations.

      après avec le code que j'ai eu au tout début, il n'y avait que ça:

      x = 5
      while x != 1: 
        if x % 2 == 1: 
          x = x * 3 + 1 
        else:   
          x = x / 2 
        print(x)


      J'ai pris 5 pour le x au début en exemple
      0
      1. Utilisateur anonyme > Thomasdu33
         
        Le problème avec le deuxième c'est qu'on ne voit pas le compteur d'itérations.

        Mais avec ce tu as, il n’y en a pas besoin
        0
      2. Thomasdu33 > Utilisateur anonyme
         
        Je comprend pas pourquoi j'en aurais pas besoin, car ils me demandent un compteur de boucle while.

        Mais je confond peut être avec "La première liste affiche, pour chaque entier de 2 à 10, le nombre d'itérations correspondant."
        Ou là oui j'en ai vraiment pas besoin
        0
      3. Utilisateur anonyme > Thomasdu33
         
        Ce que cet exemple retourne, c.est la valeur initiale de chaque x et toutes les valeurs intermédiaires (que tu peux trier et compter).

        Mais c’est aussi un exemple que peux te permettre d’inventer d’autres solutions comme celle à laquelle tu essayes d’aboutir au message 52. Je la testerai ce soir
        0
  4. Thomasdu33
     
    Maitenant, j'en suis à là

    def f():
        premiere_list = []
        deuxieme_list = []
        for x in range(2, 5):
            lesX = []
            lesX.append(x)
            while x != 1: 
                if x % 2 == 1: 
                    x = x * 3 + 1 
                else:   
                    x = x / 2
                lesX.append(x)
            premiere_list.append(sorted(lesX, reverse = True))
        deuxieme_list.append(premiere_list[][0])
            
            
        return premiere_list, deuxieme_list
    
    print(f())


    J'essais de mettre le premier nombre de chaque sous-list dans la deuxième list, mais il me faut trouver un moyen de les parcourir pour prendre les nombres les plus élever.

    c'est ici que ça me pose problème:

        deuxieme_list.append(premiere_list[][0])
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Utilisateur anonyme
     
    En repartant de ce code
    def f():
        premiere_list = []
        deuxieme_list = []
        for x in range(2, 5):
            lesX = []
            lesX.append(x)
            while x != 1: 
                if x % 2 == 1: 
                    x = x * 3 + 1 
                else:   
                    x = x / 2
                lesX.append(x)
            premiere_list.append(sorted(lesX, reverse = True))
        deuxieme_list.append(premiere_list[][0])
            
            
        return premiere_list, deuxieme_list
    
    print(f())


    Et avec ce que tu as écrit à ton premier message

    • Je dois créer une liste pour afficher de 2 à 10, le nombre d'itérations correspondant, et la liste doit être triée sur le nombre d'itérations, du plus grand nombre au plus petit.
    • Avec la deuxième liste affiche, pour chaque entier de 2 à 10, la plus grande valeur atteinte pour x correspondante, et la liste doit être triée sur la plus grande valeur atteinte, dans l'ordre décroissant.



    En première approche, on va supposer que savoir que 2 à donné 1 itération, que 3 en a donné 7 etc... n'est pas demandé (et de toute façon, tel que tu l'as écrit c'est pas clair clair), mais qu'il faut retourner 1, 7 etc...

    Dans cette même approche, que la valeur max pour 2 soit 2 (si on considère que la valeur initiale est prise en compte dans le max) ou 1 (dans le cas contraire) , pour 3 qu'elle soit 16 etc.. n'est pas demandé non plus, mais seulement 2, 16 etc...

    Il faut donc que dans premiereListe ne soit ajouté que le nombre d'itération et dans seconde liste la valeur max de x.
    Il faut penser à les trier juste avant le return.

    En appliquant ces quelques principes, tu as peu de modification du code ci dessus à faire pour obtenir un premier résultat avec
    print(f())

    ([2, 4, 8, 16.0, 16, 16.0, 52.0, 52.0], [19, 16, 8, 7, 5, 3, 2, 1])

    0
  7. Thomasdu33
     
    Bonjour Whismeril et mamiemando,

    Normalement j'ai finis, ce que je voulais faire.
    Je voulais d'abord faire mon programme avec des listes pour enfin faire la dernière consigne de mon exercice qui était d'utiliser les dictionnaires.

    Donc je suis passé de ça :

    def f(x):
        if x % 2 == 1:
            return x * 3 + 1
        else:
            return x / 2
    
    def f_iter(x):
        l = list()
        while x != 1:
            x = f(x)
            l.append(x)
        return l
    
    liste1 = list()
    liste2 = list()
    for x_initial in range(2, 10):
        values = f_iter(x_initial)
        max_value = max(values)
        num_iterations = len(values)
        sorted_values = sorted(values, reverse=True)
        liste1.append([x_initial] + sorted_values)
        liste2.append(max_value)
                                   
    print("liste1 = "+ str(liste1))
    print("-"*60)
    print("liste2 = "+ str(sorted(liste2, reverse = True)))


    à ça :

    dict1 = {}
    dict2 = {}
    cle_boucle = [2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    
    for x in cle_boucle:
      list_iteration = []
      x_original = x
      while x != 1: 
        if x % 2 == 1: 
          x = x * 3 + 1 
        else:   
          x = x / 2 
        list_iteration.append(x)
      dict1[x_original]=sorted(list_iteration, reverse = True)
      
      maximum = max(list_iteration)
      dict2[x_original]=maximum
      
    dico2 = sorted(dict2.items(), key=lambda y: y[1], reverse=True)  
      
    print("dictionnaire 1:"+ str(dict1))
    print("-"*60)
    print("dictionnaire 2:"+ str(dico2))


    Je pense qu'il me reste qu'à transformer ça en fonction, mais le plus dur est fait.

    Je vous remercie de m'avoir autant aidé, j'ai pu largement consolider mes connaissances.
    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
       
      Tant mieux, bonne continuation à toi :-)
      0
Précédent
  • 1
  • 2