Быстрый ответ:
Выполнение 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:
>>> 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]