Швидка відповідь:
Виконання 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]