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