Pour faire simple, la fonction de générateur donne l'impression qu'un «retour» peut être créé au milieu de la fonction.
Cependant, la caractéristique est que cela ne se termine pas même si vous faites quelque chose comme return
.
Aussi, je vais les retourner un par un, donc je n'utilise pas beaucoup de mémoire.
Je vais également expliquer les sous-générateurs ajoutés dans python3.
Code créé cette fois-ci: https://github.com/KodairaTomonori/Qiita/tree/master/default_module/syntax
En fait, utilisez «yield» au lieu de «return».
Tout d'abord, simplement à partir des fonctions de génération de séquence counter
et fibonatti
qui comptent
counter_and_fibonati.py
def counter():
num = 0
while True:
yield num
num += 1
def fibonatti():
now = 0
next_num = 1
while True:
yield now
now, next_num = next_num, now + next_num
if __name__ == '__main__':
count = counter()
print('print 0-3, for i in count')
for i in count:
print(i, end=', ')
if i >= 3:
print()
break
print('next_count, count.__next__()')
print(count.__next__())
print('print 5-7, for i in count')
for i in count:
print(i, end=', ')
if i >= 7:
count.close()
print()
print('print fibonatti')
for i in fibonatti():
if i > 100: break
print(i, end=', ')
print(i)
print 0-3, for i in count 0, 1, 2, 3, next_count, count.__next__() 4 print 5-7, for i in count 5, 6, 7, print fibonatti 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144
Premièrement, la fonction counter
est simple, commençant par num = 0
et entrant dans la boucle infinie while
.
Renvoie «num» avec «yield num» pour chaque boucle.
Puis a été appelé «compteur»? Parfois, «num + 1», puis «yield num» est renvoyé.
Chaque fois qu'il est appelé, une valeur «+ 1» est renvoyée.
Lors de son utilisation, il est écrit à la place de main
, mais si vous le mettez dans l'instruction for
, il renverra la valeur 0,1,2,3
séquentiellement pour chaque boucle.
Vous pouvez enregistrer son état (num
) en le définissant comme une variable avec count = counter ()
.
Utiliser count .__ next__ ()
retournera le numéro suivant, c'est-à-dire 4
.
L'instruction for suivante sera également renvoyée une par une de la même manière qu'auparavant.
Cependant, contrairement à avant, l'état de count
s'arrête à num = 4
, donc cette boucle commence à 5
.
Donc, à la fin, quand il est devenu «7» ou plus, j'ai fait «count.close ()» pour terminer la boucle.
Si vous utilisez .close ()
, vous pouvez quitter l'instruction for
et perdre la fonction en tant que générateur de count
.
Après cela, crachez count .__ next__ ()
et StopIteration
.
Le «fibonatti» est presque le même, donc il n'y a pas de problème particulier.
Ici, puisque le générateur est placé directement avec fibonatti ()
, le générateur où now, next_num
est sauvegardé ira quelque part après avoir quitté l'instruction for
.
Le fait qu'il puisse être transformé avec une instruction for
peut être transformé en une liste
en l'enfermant dans list ()
, mais dans ce cas, si vous ne définissez pas de limite dans la fonction générateur, vous mourrez dans une boucle infinie, alors soyez prudent.
Vous pouvez passer un argument à chaque fois avec .send (x)
.
Puisque .send (x)
donne x
à la position de yield
, vous devez exécuter` .__ next__ () ʻune fois.
generator_send.
def generator(step):
val = 0
prev = 0
while True:
if step == None:
step = prev
prev = step
val += step
step = yield val
if __name__ == '__main__':
gen = generator(0)
print(gen.__next__(), end=', ')
for i in [1,2,3,4,5,6]:
print(gen.send(i) , end=', ')
print()
0, 1, 3, 6, 10, 15, 21,
La fonction generator
est un programme qui ajoute l'argument reçu step
à val
.
Tout d'abord, définissez la valeur initiale de générateur (0)
sur 0.
Utilisez ensuite .__ next__ ()
pour aller à step = yield val
.
Ensuite, «0» sera renvoyé.
Entrez ensuite l'instruction for et passez de «1 à 6».
Lorsque gen.send (i)
est exécuté, ʻi est entré à l'étape précédente = yield val
.
En d'autres termes, si vous faites gen.send (i)
, vous obtenez step = i
.
Je vais faire une boucle comme ça. Ici, si vous faites .__ next __ ()
sans utiliser .send ()
, vous obtiendrez step = None
.
Le sous-générateur exécutera le générateur si vous faites rendement du générateur
.
«générateur» est une fonction de générateur.
Cela rend la récurrence très pratique.
Un exemple de programme pour générer une séquence contenant la même séquence est présenté ci-dessous.
ex_permutation.py
def ex_permutation(iterable, now_list=[]):
if not iterable:
yield now_list
return
for i in [iterable.index(i) for i in set(iterable) ]:
yield from permutation(iterable[:i] + iterable[i+1:], now_list + [iterable[i] ])
if __name__ == '__main__':
permu = ex_permutation([2,2,3])
for i in permu:
print(i)
[2, 2, 3] [2, 3, 2] [3, 2, 2]
Je me fiche de ce qu'il y a à l'intérieur, mais je le fais juste récursivement en utilisant set ()
pour qu'il ne soit pas couvert.
Vous pouvez donc écrire récursivement avec yield from
.
Enfin, il retourne now_list
lorsque le contenu de ʻiterable` est épuisé.
Je ne sais pas ce que c'est, mais c'est pratique!
Sans cela, cela semble déroutant.
Vous pouvez renvoyer une valeur au milieu de la fonction avec yield
.
Vous pouvez terminer la fonction du générateur avec .close ()
.
Faites ce qui suit avec .__ next__ ()
Vous pouvez passer une valeur avec .send ()
«rendement de» est pratique.
Recommended Posts