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
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 def f1(n): for i in range(n) : yield i*iCes 2 fonctions font sensiblement la même chose :
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
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.
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)
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)))
Salut,
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
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
Bonjour
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
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.
Code python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 def f(): return (1, 2, 3, 4, 5)
Si maintenant "f" a été écrite ainsi
Alors chaque valeur sera générée au moment où la boucle arrive dessus et non pas au moment où la boucle commence.
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
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.
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]
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)
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 !
PS : Il faut laisser la balise fermante [ /CODE ] à la fin de votre message, car sinon votre code n'apparait pas comme tel...
Code : Sélectionner tout - Visualiser dans une fenêtre à part print( list(mon_generateur) )
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"...
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]
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager