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 :

Problème avec la permutation des élements


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2021
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2021
    Messages : 59
    Par défaut Problème avec la permutation des élements
    Bonjour tout le monde,

    Je suis un peu nouveau en python. Je dois implémenter un petit problème pour permuter tous les éléments de liste. Il y a une méthode toute faite, mais il m'a été imposé d'utiliser la méthode récursive. Donc je suis allé sur internet. J'ai récupérer un programme pour pouvoir m'adapter sur mon problème. Pour comprendre, j'ai placé des prints. Mais je rencontre des difficultés surtout avec la fonction yield. Sur documentation, il est indiqué qu'il crée un objet. Puis il prend des valeurs à la volé. Je voudrai savoir pourquoi mon print ne marche pas. Si vous pouvez éclairer un peu sur le fonctionnement de yield je vous serai reconnaissance.
    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 all_perms(elements):
        if (len(elements) <=1):
            yield elements
        else :
            for perm in all_perms(elements[1:]):
                print("\n")
                for i in range(len(elements)):
                    yield perm[:i]+elements[0:1]+perm[i:]
                    print(elements)
                    print("\n")
                    print(perm)
     
     
     
     
    b1 = [1,2,3]
    bn = all_perms(b1)

    il compile mais, il m'affiche rien

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    yield fabrique un générateur. Ca ressemble a une fonction mais çà sert à fabriquer un générateur qui contrairement a une fonction aura un état... et qui sera un itérable.

    A la dernière ligne remplacez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for bn in all_perms(b1):
         print(bn)
    mais si on vous a demandé d'utiliser une méthode récursive, c'est que çà a son intérêt sans générateur surtout pour ce qui est de la construction de la liste à retourner.
    note: si en plus on vous a interdit d'utiliser la solution toute faite, est ce que ça vous permet de la recopier?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par tuba uba Voir le message
    Mais je rencontre des difficultés surtout avec la fonction yield. Sur documentation, il est indiqué qu'il crée un objet. Puis il prend des valeurs à la volé. Si vous pouvez éclairer un peu sur le fonctionnement de yield je vous serai reconnaissance.
    yield permet de créer un générateur, c'est à dire un truc qui génère ses résultats non pas au moment où l'instruction est lue mais au moment où celle-ci est réelleemnt exécutée.

    Python permet de créer des fonctions qui renvoient d'un coup plusieurs éléments sous forme de listes ou de tuples (exemple def fct(): return (1, 2, 3, 4, 5)). Cette fonction renvoyant 5 entiers, l'appelant pourra l'utiliser de cette façon: for x in fct(): print(x).

    Mais là arrive un souci inhérent avec la quantité de valeurs retournées par rapport au temps de traitement. Si ton code met (par exemple) 1h pour traiter chaque valeur, il est alors possible que la dernière valeur (ici 5) ait perdu sa pertinence étant traitée 4h après avoir été créée.
    Exemple2
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from datetime import *
    import time
     
    def fct(x):
    	ret=[]
    	for i in range(x):
    		ret.append(datetime.today().strftime("%H:%M:%S"))
    	return ret
     
    for (i, f) in enumerate(fct(5), 1):
    	print(i, f)
    	time.sleep(5)
    Dans cet exemple qui prendra 25 secondes pour s'exécuter, on aura 5 fois la même heure. Il est évident que la dernière ligne n'aura pas de rapport avec la réalité (l'heure affichée par le programme ne sera plus celle de la réalité).

    C'est là qu'entrent en jeux les générateurs. Ils permettent à la fonction de "générer" la valeur au moment où l'appelant en a réellement besoin. Cela se fait au travers du yield qui renvoie l'info demandée (comme un return) mais qui garde trace de la position du code. Et à l'appel suivant, il reprend de cette position pour générer et renvoyer la valeur suivante.
    Voici comment je peux réécrire ma première fonction avec un yield
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def fct():
    	yield 1
    	yield 2
    	yield 3
    	yield 4
    	yield 5
    Ou (plus simplement) def fct(): yield from (1, 2, 3, 4, 5). Du côté appelant, rien ne change, c'est transparent pour lui. Il peut parfaitement garder sa boucle for x in fct(): print(x). Au premier appel, la fonction retourne 1. Au second appel, elle repart du 1 pour continuer son travail et retourne 2 et etc.

    Exemple 2
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from datetime import *
    import time
     
    def fct(x):
    	for i in range(x):
    		yield datetime.today().strftime("%H:%M:%S")
     
    for (i, g) in enumerate(fct(5), 1):
    	print(i, g)
    	time.sleep(5)
    Ici les heures affichées seront celles du moment réel de l'affichage. Le générateur a résolu ce problème tout en restant compatible avec l'appelant qui, lui, ne change pas sa façon de faire. Et ça c'est important. Simplement on ne peut pas afficher un générateur. Si j'écris def fct(): return (1, 2, 3, 4, 5) je peux utiliser fct dans une boucle ou bien afficher d'un coup tout son contenu (print(fct())). Si je passe par yield, je ne peux plus l'afficher directement (je peux toutefois toujours convertir le générateur en tuple au moment de l'affichage => print(tuple(fct())).

    Citation Envoyé par tuba uba Voir le message
    mais il m'a été imposé d'utiliser la méthode récursive
    Oui, c'est assez basique comme méthode. Permuter "abc" en récursif c'est "a" suivi des permutations de "bc" puis "b" suivi des permutations de "ac" puis "c" suivi des permutations de "ab". Et rebelote pour les permutations de "ab", "ac" et "bc".

    Citation Envoyé par tuba uba Voir le message
    je suis un peu nouveau en python
    Peut-être alors n'es-tu pas prêt pour le yield qui, me semble-t-il, ne t'a pas été imposé lui (récursif n'implique pas forcément d'être géré par du yield)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Problème avec la gestion des événements
    Par CynO dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/10/2005, 10h07
  2. problème avec l'affichage des caractères spéciaux
    Par michelkey dans le forum Général Python
    Réponses: 4
    Dernier message: 19/08/2005, 08h09
  3. Réponses: 2
    Dernier message: 16/01/2005, 23h18
  4. [SWT] Problème avec la transparence des PNG
    Par sirjuh dans le forum SWT/JFace
    Réponses: 1
    Dernier message: 02/08/2004, 08h07
  5. Réponses: 11
    Dernier message: 16/12/2003, 19h58

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