Быстрый ответ:
Обращение list()с выражением генератора (почти) в точности эквивалентно заключению его в []скобки. Так что да, ты можешь сделать
>>> list((x for x in string.letters if x in (y for y in "BigMan on campus")))
Но вы также можете сделать
>>> [x for x in string.letters if x in (y for y in "BigMan on campus")]
Да, это превратит выражение генератора в понимание списка. То же самое и со списком вызовов (). Таким образом, чтобы преобразовать выражение генератора в список, нужно заключить его в скобки.
Детальное объяснение:
Выражение генератора - это «голое» forвыражение. Вот так:
x*x for x in range(10)
Теперь вы не можете вставить это в отдельную строку, вы получите синтаксическую ошибку. Но вы можете заключить его в скобки.
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7485464>
Иногда это называют пониманием генератора, хотя я думаю, что официальное название по-прежнему является выражением генератора, на самом деле нет никакой разницы, скобки нужны только для того, чтобы синтаксис был действительным. Они вам не нужны, если вы передаете его как единственный параметр функции, например:
>>> sorted(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
По сути, все другие понимания, доступные в Python 3 и Python 2.7, представляют собой просто синтаксический сахар вокруг выражения генератора. Установить понимание:
>>> {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((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}
И перечислите понимание в 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]
В Python 2 понимание списков - это не просто синтаксический сахар. Но единственная разница в том, что x будет в Python 2 просачиваться в пространство имен.
>>> x
9
В Python 3 вы получите
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Это означает, что лучший способ получить красивую распечатку содержимого выражения генератора на Python - это составить из него список! Однако это явно не сработает, если у вас уже есть объект-генератор. В результате будет создан список из одного генератора:
>>> foo = (x*x for x in range(10))
>>> [foo]
[<generator object <genexpr> at 0xb7559504>]
В этом случае вам нужно будет позвонить list():
>>> list(foo)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Хотя это работает, но глупо:
>>> [x for x in foo]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]