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 :

différence yield et return


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2019
    Messages : 7
    Points : 6
    Points
    6
    Par défaut différence yield et return
    bonjour je voudrai connaître la différence entre yield et return et dans quel cas les utilisés. je sais juste que ce son des générateur. merci

  2. #2
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def f1(n):
        for i in range(n) :
            yield i*i
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def f2(n):
         res=[]
         for i in range(10) :
              res.append(i*i)
         return res
    Ces 2 fonctions font sensiblement la même chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for x in f1(10):
        print(x)
     
    for x in f2(10):
        print(x)
    Sauf que comme vous l'avez dit, f1 est un générateur. La différence avec un générateur c'est que la liste entière des carrées n'est jamais calculée. Chacun des termes est calculé au fur et à mesure de la boucle for. Si c'est une très grande liste, ca vous évite d'avoir à la stocker en mémoire, et cela rend la fonction plus rapide.

    C'est le principe du générateur : vous avez une "formule" pour calculer l'élément suivant lorsqu'on fait une itération. Vous pouvez toujours retrouver une liste depuis un générateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    print(f1(10))
    print(f2(10))
    print(list(f1(10)))

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par Gailletan2 Voir le message
    bonjour je voudrai connaître la différence entre yield et return et dans quel cas les utilisés. je sais juste que ce son des générateur. merci
    Le générateurs, contrairement aux fonctions, sont de vrais objets et ont tellement d'applications qu'un peu de recherche sur Internet pourrait vous en montrer quelques unes. En tous cas, c'est pas en quelques lignes qu'on va pouvoir vous montrer combien ils sont différents et autrement puissants que les simples fonctions.

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

  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,

    Exemple simple: les 2 fonctions glob et iglob du module glob. Ces fonctions renvoient les fichiers stisfaisant un motif de recherche) d'un répertoire donnée du disque:

    glob renvoie la liste complète
    iglob renvoie les fichiers un par un, grâce au "yield"

    Il existe plusieurs raisons de préférer l'un à l'autre:

    Si on veut afficher la liste triée (sur la date, par exemple), il faut la liste complète avec glob.
    Si on veut filtrer les fichiers (savoir lesquels on retient par exemple), il vaut mieux les filtrer un par un avec iglob.
    Si on a un gros disque avec beaucoup de fichiers et peu de mémoire, on peut éviter une trop grosse liste avec iglob.
    etc...

    A noter tout de même que si l'on a déjà une fonction avec yield, il est facile d'avoir l’équivalent d'une fonction avec return avec, par exemple: list(iglob(...)) qui donne la même liste que glob(...).
    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
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Citation Envoyé par Gailletan2 Voir le message
    je sais juste que ce sont des générateurs
    yield est générateur. return n'en est pas un.
    Et justement, la différence c'est que le générateur "genère" l'info au moment où tu vas la traiter, et non pas au moment où tu as appelé la fonction.

    Prenons l'exemple de base: for x in f(): print(x).
    Ou plus parlant
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for x in f():
        print(x)
        ...(attente 15 mn)...

    Si "f" a été écrite ainsi
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def f():
        return (1, 2, 3, 4, 5)
    Alors tu n'as aucun changement d'état. Le premier item vaut "1" et le dernier vaut "5" et ce dernier vaut "5" de façon invariante du début de la boucle jusqu'à sa fin 75 minutes plus tard. Rien ne peut modifier cet état.

    Si maintenant "f" a été écrite ainsi
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def f():
        yield 1
        yield 2
        yield 3
        yield 4
        yield 5
    Alors chaque valeur sera générée au moment où la boucle arrive dessus et non pas au moment où la boucle commence.
    Dans ce cas précis ça importe peu (les valeurs sont figées). Mais si la valeur dépend d'un état de ton programme (l'heure locale, un contenu de bdd, etc) alors ça devient bien plus important d'utiliser yield plutôt que return.

    Citation Envoyé par Gailletan2 Voir le message
    et dans quel cas les utiliser
    Chaque fois que tu auras plusieurs items à renvoyer en séquentiel ; et que le moment du traitement de tes items entrera en ligne de compte dans le résultat de ton code. Et comme qui peut le plus peut le moins, tu auras tout avantage à utiliser le yield en fait à chaque fois.
    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]

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2019
    Messages : 7
    Points : 6
    Points
    6
    Par défaut bonjour merci pour votre aide, j'ai crée une fonction avec un générateur , j'obtiens l'adresse mémoire
    j'air crée une fonction qui parcourt le module string, est qui renvoi ce quelle parcours par paquet de 5 , cependant l'or du lancement j'obtiens.

    <generator object ch at 0x104d85e58>
    au lieu des valeur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import string as s
    d = s.printable
     
     
    def ch(d):
        a = d
        while len(a) <5:
            for i in a:
                yield(a)

  7. #7
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    1) Vous ne montrez pas comment vous appelez votre fonction.

    2) Vos paquets de 5 me paraissent très bizarre. Si votre fonction retourne des paquets de 5, alors après yield je dois voir soit 5 valeurs, soit 1 paquets de 5 valeurs. Là c'est pas du tout le cas. Faites la fonction avec un return tout simple déjà et voyez si ca marche. Ce n'est qu'ensuite que vous changerez le return en yield.

    3) Une fonction contenant un yield, retourne toujours un générateur. C'est normal, yield est fait pour ca ! Si vous voulez voir ce que contient ce générateur, transformez le en liste !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print( list(mon_generateur) )
    PS : Il faut laisser la balise fermante [ /CODE ] à la fin de votre message, car sinon votre code n'apparait pas comme tel...

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    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 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gailletan2 Voir le message
    j'air crée une fonction qui parcourt le module string, est qui renvoi ce quelle parcours par paquet de 5
    Je suis désolé mais ton algo ne fait pas ce que tu décris.
    Déjà écrire while len(a) < 5 alors que "a" ne varie pas amène alors soit ta boucle à se répéter de façon infinie, soit à ne jamais commencer.
    Et ensuite écrire for i in a pour terminer par un piteux yield a m'amène à me demander à quoi sert "i"...

    Citation Envoyé par Gailletan2 Voir le message
    cependant l'or du lancement j'obtiens <generator object ch at 0x104d85e58> au lieu des valeur
    Tu affiches le générateur tel quel au lieu d'afficher ce qu'il génère.

    Si tu reprends mon exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def f():
        yield 1
        yield 2
        yield 3
        yield 4
        yield 5

    Tu ne peux que traiter les retours de la fonction, pas la fonction elle-même. Donc tu peux afficher ses valeurs ainsi: for x in f(): print(x) ou ainsi print(tuple(f())) (dans ce cas tu demandes une transformation explicite du générateur en tuple avant d'afficher ce dernier). Mais si tu tentes un print(f()) tu affiches alors littéralement la nature de f et non ses valeurs. Et f est un générateur.
    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. différence entre return et print
    Par titus712 dans le forum Général Python
    Réponses: 2
    Dernier message: 24/12/2009, 17h29
  2. Différence entre die et return
    Par Jcpan dans le forum Langage
    Réponses: 3
    Dernier message: 14/09/2009, 17h07
  3. [2005 / CLR TVF] yield return ?
    Par Dude76 dans le forum Développement
    Réponses: 3
    Dernier message: 11/06/2009, 15h10
  4. yield return et liste générique ?
    Par Thomas Lebrun dans le forum C#
    Réponses: 4
    Dernier message: 18/07/2007, 13h16
  5. "yield return" en VB
    Par Matthieu MEZIL dans le forum VB.NET
    Réponses: 3
    Dernier message: 06/02/2007, 13h58

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