Que fait la compréhension du générateur? Comment ça marche? Je n'ai pas trouvé de tutoriel à ce sujet.
Que fait la compréhension du générateur? Comment ça marche? Je n'ai pas trouvé de tutoriel à ce sujet.
Réponses:
Comprenez-vous les compréhensions de listes? Si tel est le cas, une expression de générateur 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 renvoie 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, cela peut entraîner d'importantes économies dans l'utilisation de la mémoire. Les expressions de générateur ont le plus de sens dans les scénarios où vous devez prendre un élément à la fois, effectuer de nombreux calculs en fonction 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.
next(...)place de .__next__()Python 3.
If you need more than one value, you can also use a generator expression and grab a few at a time. Pourriez-vous s'il vous plaît donner un exemple de cette utilisation? Merci.
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 ici et pour les générateurs, voir ici .
La compréhension de liste / générateur est une construction que vous pouvez utiliser pour créer une nouvelle liste / générateur à partir d'un existant.
Supposons que vous souhaitiez 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 la rangefonction 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>
En Python 3, cependant, il rangey a un générateur, donc le résultat ne dépend que de la syntaxe que vous utilisez (crochets ou crochets).
La compréhension des générateurs est un moyen simple de créer des générateurs avec une certaine structure. Disons que vous voulez ungenerator qui sort un par un tous les nombres pairs your_list. Si vous le créez en utilisant le style de fonction, ce serait comme ceci:
def allEvens( L ):
for number in L:
if number % 2 is 0:
yield number
evens = allEvens( yourList )
Vous pouvez 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 numéro pair suivant your_list.
La compréhension du générateur est une approche pour créer des itérables, quelque chose comme un curseur qui se déplace sur une ressource. Si vous connaissez le curseur mysql ou le curseur mongodb, vous savez peut-être que toutes les données réelles ne sont jamais chargées dans la mémoire à la fois, mais une à la fois. Votre curseur se déplace d'avant en arrière, mais il y a toujours un élément d'une ligne / liste en mémoire.
En bref, en utilisant la compréhension des générateurs, vous pouvez facilement créer des curseurs en python.
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