114 votes

Comment fonctionne exactement la compréhension d'un générateur ?

Que fait la compréhension du générateur ? Comment fonctionne-t-elle ? Je n'ai pas trouvé de tutoriel à ce sujet.

3 votes

Pour être clair, le nom de la langue pour ceux-ci est "générateur". expressions pas de générateur compréhensions .

4 votes

@ShadowRanger Il y a une discussion sur la Liste de diffusion Python-dev en juillet 2018 sur "la syntaxe de la compréhension des noms". où il y a eu un accord provisoire mais assez unanime pour les appeler "compréhensions de générateur" par souci de cohérence.

174voto

gotgenes Points 8667

Comprenez-vous la compréhension des listes ? Si c'est le cas, une expression génératrice est comme une compréhension de liste, mais au lieu de trouver tous les éléments qui vous intéressent et de les regrouper dans une liste, elle attend, et produit chaque élément de l'expression, un par un.

>>> my_list = [1, 3, 5, 9, 2, 6]
>>> filtered_list = [item for item in my_list if item > 3]
>>> print(filtered_list)
[5, 9, 6]
>>> len(filtered_list)
3
>>> # compare to generator expression
... 
>>> filtered_gen = (item for item in my_list if item > 3)
>>> print(filtered_gen)  # notice it's a generator object
<generator object <genexpr> at 0x7f2ad75f89e0>
>>> len(filtered_gen) # So technically, it has no length
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> # We extract each item out individually. We'll do it manually first.
... 
>>> next(filtered_gen)
5
>>> next(filtered_gen)
9
>>> next(filtered_gen)
6
>>> next(filtered_gen) # Should be all out of items and give an error
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> # Yup, the generator is spent. No values for you!
... 
>>> # Let's prove it gives the same results as our list comprehension
... 
>>> filtered_gen = (item for item in my_list if item > 3)
>>> gen_to_list = list(filtered_gen)
>>> print(gen_to_list)
[5, 9, 6]
>>> filtered_list == gen_to_list
True
>>> 

Étant donné qu'une expression de générateur ne doit produire qu'un seul élément à la fois, elle peut permettre de réaliser d'importantes économies de mémoire. Les expressions de générateur sont les plus utiles dans les scénarios où vous devez prendre un élément à la fois, effectuer de nombreux calculs sur la base de cet élément, puis passer à l'élément suivant. Si vous avez besoin de plus d'une valeur, vous pouvez également utiliser une expression de générateur et en saisir quelques-unes à la fois. Si vous avez besoin de toutes les valeurs avant de poursuivre votre programme, utilisez plutôt une compréhension de liste.

4 votes

Une question ici. J'ai utilisé next(gen_name) pour obtenir le résultat et cela a fonctionné en Python 3. Existe-t-il un scénario spécifique où nous devons utiliser __next__() ?

4 votes

@AnkitVashistha Non, utilisez toujours next(...) au lieu de .__next__() dans Python 3.

2 votes

@gotgenes @AnkitVashistha If you need more than one value, you can also use a generator expression and grab a few at a time . Pourriez-vous donner un exemple de cette utilisation ? Merci.

29voto

rz. Points 7261

Une compréhension de générateur est la version paresseuse d'une compréhension de liste.

C'est comme une compréhension de liste sauf qu'elle renvoie un itérateur au lieu de la liste, c'est-à-dire un objet avec une méthode next() qui donnera l'élément suivant.

Si vous n'êtes pas familier avec les compréhensions de listes, voir aquí et pour les générateurs, voir aquí .

4 votes

A generator comprehension is the lazy version of a list comprehension est probablement l'une des meilleures explications en une ligne que j'ai jamais lues. Merci !

1 votes

Je suis heureux que vous ayez trouvé cela utile ! :)

6voto

Can Berk Güder Points 39887

La compréhension des listes/générateurs est une construction que vous pouvez utiliser pour créer une nouvelle liste/générateur à partir d'une liste existante.

Disons que vous voulez générer la liste des carrés de chaque nombre de 1 à 10. Vous pouvez le faire en Python :

>>> [x**2 for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

ici, range(1,11) génère la liste [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] mais le range n'est pas un générateur avant Python 3.0, et donc la construction que j'ai utilisée est une compréhension de liste.

Si je voulais créer un générateur qui fasse la même chose, je pourrais le faire comme ceci :

>>> (x**2 for x in xrange(1,11))
<generator object at 0x7f0a79273488>

Dans Python 3, cependant, range est un générateur, donc le résultat ne dépend que de la syntaxe que vous utilisez (crochets ou parenthèses).

4 votes

C'est faux. Le fait que l'expression externe soit un générateur n'a rien à voir avec le fait que l'expression interne le soit. Bien que, de toute évidence, il n'y ait généralement pas beaucoup d'intérêt à ce qu'une expression de générateur prenne des éléments d'une liste, vous pouvez le faire.

0 votes

Peut-on réécrire cela plus clairement ? Je comprends ce que vous dites, mais comme le dit Antimony, on dirait que vous dites autre chose. (et la chose que vous semblez dire est fausse)

5voto

Cristian Garcia Points 805

La compréhension des générateurs est un moyen facile de créer des générateurs avec une certaine structure. Disons que vous voulez un generator qui sort un par un tous les nombres pairs dans your_list . Si vous le créez en utilisant le style de fonction, ce sera comme ceci :

def allEvens( L ):
    for number in L:
        if number % 2 is 0:
            yield number

evens = allEvens( yourList )

Vous pourriez obtenir le même résultat avec cette expression de compréhension du générateur :

evens = ( number for number in your_list if number % 2 == 0 )

Dans les deux cas, lorsque vous appelez next(evens) vous obtenez le prochain nombre pair dans your_list .

2voto

AMIT KUMAR Points 31

Un autre exemple de compréhension du Générateur :

print 'Generator comprehensions'

def sq_num(n):
    for num in (x**2 for x in range(n)):    
        yield num

for x in sq_num(10):
    print x

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X