Dans le shell Python, si j'entre une compréhension de liste telle que:
>>> [x for x in string.letters if x in [y for y in "BigMan on campus"]]
J'obtiens un résultat bien imprimé:
['a', 'c', 'g', 'i', 'm', 'n', 'o', 'p', 's', 'u', 'B', 'M']
Idem pour une compréhension de dictionnaire:
>>> {x:x*2 for x in range(1,10)}
{1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}
Si j'entre une expression de générateur, je n'obtiens pas une réponse aussi amicale:
>>> (x for x in string.letters if x in (y for y in "BigMan on campus"))
<generator object <genexpr> at 0x1004a0be0>
Je sais que je peux le faire:
>>> for i in _: print i,
a c g i m n o p s u B M
En dehors de cela (ou en écrivant une fonction d'assistance), puis-je facilement évaluer et imprimer cet objet générateur dans le shell interactif?
generator object
car je construis interactivement une compréhension à l'invite interactive. L'appellist(_)
fait ça. Ce que j'ai fait, c'est utiliser des compréhensions de liste, puis les transformer en genexp dans un code plus grand. Celles-ci peuvent échouer au moment de l'exécution d'une manière que les compréhensions de liste ne font pas.list()
, puis les imprimer.Réponses:
Réponse rapide:
Faire le
list()
tour d'une expression de générateur équivaut (presque) exactement à avoir des[]
crochets autour d'elle. Alors oui, tu peux faireMais tu peux tout aussi bien faire
Oui, cela transformera l'expression du générateur en une compréhension de liste. C'est la même chose et la liste d'appels () dessus. Ainsi, la manière de transformer une expression de générateur en liste est de la mettre entre crochets.
Explication détaillée:
Une expression génératrice est une expression «nue»
for
. Ainsi:Maintenant, vous ne pouvez pas coller cela sur une ligne seule, vous obtiendrez une erreur de syntaxe. Mais vous pouvez mettre des parenthèses autour.
Cela s'appelle parfois une compréhension du générateur, même si je pense que le nom officiel est toujours l'expression du générateur, il n'y a pas vraiment de différence, les parenthèses ne sont là que pour rendre la syntaxe valide. Vous n'en avez pas besoin si vous le transmettez comme seul paramètre à une fonction, par exemple:
Fondamentalement, toutes les autres compréhensions disponibles dans Python 3 et Python 2.7 ne sont que du sucre syntaxique autour d'une expression de générateur. Définir les compréhensions:
Compréhensions de dictées:
Et lister les compréhensions sous Python 3:
Sous Python 2, la compréhension de liste n'est pas seulement du sucre syntaxique. Mais la seule différence est que x va sous Python 2 s'infiltrer dans l'espace de noms.
Sous Python 3, vous obtiendrez
Cela signifie que la meilleure façon d'obtenir une belle impression du contenu de votre expression de générateur en Python est d'en faire une compréhension de liste! Cependant, cela ne fonctionnera évidemment pas si vous avez déjà un objet générateur. Faire cela fera juste une liste d'un générateur:
Dans ce cas, vous devrez appeler
list()
:Bien que cela fonctionne, mais c'est un peu stupide:
la source
list( generator-expression )
n'imprime pas l'expression du générateur; il génère une liste (puis l'imprime dans un shell interactif). Au lieu de générer une liste, dans Python 3, vous pouvez splater l'expression du générateur dans une instruction d'impression. Ie)print(*(generator-expression))
. Cela imprime les éléments sans virgules et sans crochets au début et à la fin.Contrairement à une liste ou à un dictionnaire, un générateur peut être infini. Cela ne fonctionnerait pas:
De plus, la lecture d'un générateur le change, il n'y a donc pas de moyen parfait de le visualiser. Pour voir un échantillon de la sortie du générateur, vous pouvez faire
la source
[next(g1) for i in range(10)]
en Python 3.Vous pouvez simplement envelopper l'expression dans un appel à
list
:la source
Ou vous pouvez toujours
map
sur un itérateur, sans avoir besoin de créer une liste intermédiaire:la source
la source