Avant d'aborder les générateurs nous allons voir les itérateurs, car un générateur est un type d'itérateur. Un itérateur est une séquence que l'on peut appliquer sur une boucle for. Il implémente des fonctions next() et iter() pour parcourir les éléments
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 my_list = [1, 2, 3, 4] print(type(my_list)) my_iter = iter(my_list) print(my_iter) # Extract the first element print(next(my_iter)) # Extract the second element print(my_iter.next()) # or my_iter.__next__() for i in my_iter: print i > <type 'list'> > <listiterator object at 0x0000000004023358> > 1 > 2 > 3 > 4
Après ce petit rappel on attaque…
Le yield est une instruction permettant de retourner un générateur, c'est-à-dire un objet python permettant de gérer plus facilement des itérateurs (chaine de caractères, liste, fichier… qui possède un index)
Un générateur retourne la valeur à la volée et ne stock rien en mémoire contrairement à un itérateur.
Un générateur ne s'exécute pas tant que l'on n'itère pas dessus.
On retrouve cette spécification dans la PEP 255
À chaque fois que python rencontre un yield il retourne la valeur du générateur.
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def create_generator() : my_list = range(3) for i in my_list: yield i*i generator = create_generator() print(generator) # It's a generator for i in generator: print(i) > <generator object create_generator at 0x00000000048BCFC0> > 0 > 1 > 4
Depuis la version python 3.3 décrit dans la PEP 380 il est possible d'utiliser
yield fromforCopier le code
1 2 3 4 5 6 7 8 9 def create_generator() : yield from map(lambda i: i*i, range(3)) for v in create_generator(): print(v) > 0 > 1 > 4
Il existe une librairie qui permet de gérer les itérateurs : itertools
Elle contient une liste de fonction utiles qui permet de faire des traitements sur des séquences et de retourner un itérateur
Voici quelques exemples
Copier le code
1 2 3 4 5 6 7 8 9 import itertools # Return iterator with all combinaisons on 2 elements for x in itertools.permutations(['a', 'b', 'c'], 2): print(x) # Return iterator after Filter on list apply for x in itertools.ifilter(lambda t: t > 2, [1, 2, 3, 4, 5]): print(x)
Et voilà rien de bien compliqué, maintenant il vous reste plus qu'à l'utiliser dans vos scripts !