Je tombe sur ce code de pymotw.com dans la section fusion et fractionnement.
from itertools import *
def make_iterables_to_chain():
yield [1, 2, 3]
yield ['a', 'b', 'c']
for i in chain.from_iterable(make_iterables_to_chain()):
print(i, end=' ')
print()
Je ne peux pas comprendre comment make_iterables_to_chain () fonctionne. Il contient deux déclarations de rendement, comment ça marche? Je sais comment fonctionnent les générateurs mais là mais il n'y avait qu'un seul rendement déclaration.
Aidez-moi, s'il vous plaît!
De la même manière, un seul yield
fonctionne.
Vous pouvez avoir autant de yield
s que vous le souhaitez dans un générateur, lorsque __next__
est appelé dessus, il s'exécutera jusqu'à ce qu'il tombe sur le prochain rendement. Vous récupérez ensuite l'expression produite et le générateur s'arrête jusqu'à ce qu'il soit __next__
la méthode est à nouveau invoquée.
Exécutez quelques appels next
sur le générateur pour voir ceci:
>>> g = make_iterables_to_chain() # get generator
>>> next(g) # start generator, go to first yield, get result
[1, 2, 3]
>>> next(g) # resume generator, go to second yield, get result
['a', 'b', 'c']
>>> # next(g) raises Exception since no more yields are found
Un générateur permet effectivement à une fonction de retourner plusieurs fois. Chaque fois qu'une instruction yield
est exécutée, la valeur est renvoyée à l'appelant et l'appelant peut continuer l'exécution de la fonction.
Habituellement, ils sont utilisés comme itérables dans les boucles for
.
La fonction suivante incrémente chaque élément d'un itérable d'un montant:
def inc_each(nums, inc):
for i in nums:
yield i + inc
Voici un exemple d'utilisation:
gen = inc_each([1, 2, 3, 4], 100)
print(list(gen)) # [101, 102, 103, 104]
list
est utilisé ici pour convertir un itérable arbitraire (dans ce cas un générateur) en une liste.
La fonction que vous décrivez exécute deux instructions de rendement:
def make_iterables_to_chain():
yield [1, 2, 3]
yield ['a', 'b', 'c']
Si vous l'appelez, il retourne un générateur qui, s'il est itéré, donne les listes [1, 2, 3]
et ['a', 'b', 'c']
.
gen = make_iterables_to_chain()
print(list(gen)) # [[1, 2, 3], ['a', 'b', 'c']]
itertools.chain.from_iterable
prendra un (éventuellement infini) itérable d'itérables et "l'aplatira", retournant un (possible infini) itérable comme résultat.
Voici un moyen de le mettre en œuvre:
def from_iterable(iterables):
for iterable in iterables:
for i in iterable:
yield i