Respuesta rápida:
Hacer list()alrededor de una expresión generadora es (casi) exactamente equivalente a tener []corchetes alrededor. Así que sí, puedes hacer
>>> list((x for x in string.letters if x in (y for y in "BigMan on campus")))
Pero también puedes hacerlo
>>> [x for x in string.letters if x in (y for y in "BigMan on campus")]
Sí, eso convertirá la expresión del generador en una lista de comprensión. Es lo mismo y lista de llamadas () en él. Entonces, la forma de convertir una expresión generadora en una lista es ponerla entre corchetes.
Explicación detallada:
Una expresión generadora es una expresión "desnuda" for. Al igual que:
x*x for x in range(10)
Ahora, no puede pegar eso en una línea por sí solo, obtendrá un error de sintaxis. Pero puedes ponerlo entre paréntesis.
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7485464>
Esto a veces se llama comprensión del generador, aunque creo que el nombre oficial sigue siendo expresión del generador, en realidad no hay ninguna diferencia, los paréntesis solo están ahí para que la sintaxis sea válida. No los necesita si lo pasa como el único parámetro a una función, por ejemplo:
>>> sorted(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Básicamente, todas las demás comprensiones disponibles en Python 3 y Python 2.7 son solo azúcar sintáctica alrededor de una expresión generadora. Establecer comprensiones:
>>> {x*x for x in range(10)}
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
>>> set(x*x for x in range(10))
{0, 1, 4, 81, 64, 9, 16, 49, 25, 36}
Dict comprensiones:
>>> dict((x, x*x) for x in range(10))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>> {x: x*x for x in range(10)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
Y enumere las comprensiones en Python 3:
>>> list(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
En Python 2, las listas por comprensión no son solo azúcar sintáctica. Pero la única diferencia es que x bajo Python 2 se filtrará en el espacio de nombres.
>>> x
9
Mientras esté bajo Python 3, obtendrá
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Esto significa que la mejor manera de obtener una buena impresión del contenido de su expresión generadora en Python es hacer una lista de comprensión. Sin embargo, esto obviamente no funcionará si ya tiene un objeto generador. Hacer eso solo hará una lista de un generador:
>>> foo = (x*x for x in range(10))
>>> [foo]
[<generator object <genexpr> at 0xb7559504>]
En ese caso, deberá llamar a list():
>>> list(foo)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Aunque esto funciona, pero es un poco estúpido:
>>> [x for x in foo]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]