Szybka odpowiedź:
Obchodzenie list()się z wyrażeniem generatora jest (prawie) dokładnie równoważne z []otaczaniem go nawiasami. Więc tak, możesz to zrobić
>>> list((x for x in string.letters if x in (y for y in "BigMan on campus")))
Ale równie dobrze możesz to zrobić
>>> [x for x in string.letters if x in (y for y in "BigMan on campus")]
Tak, to zmieni wyrażenie generatora w rozumienie listy. To to samo i lista wywołań () na nim. Tak więc sposobem na przekształcenie wyrażenia generatora w listę jest umieszczenie wokół niego nawiasów.
Szczegółowe wyjaśnienie:
Wyrażenie generatora to wyrażenie „nagie” for. Tak jak to:
x*x for x in range(10)
Teraz nie możesz umieścić tego samego w linii, otrzymasz błąd składni. Ale możesz umieścić to w nawiasach.
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7485464>
Nazywa się to czasem zrozumieniem generatora, chociaż myślę, że oficjalna nazwa nadal jest wyrażeniem generatora, tak naprawdę nie ma żadnej różnicy, nawiasy są tylko po to, aby składnia była poprawna. Nie potrzebujesz ich, jeśli przekazujesz je jako jedyny parametr do funkcji, na przykład:
>>> sorted(x*x for x in range(10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Zasadniczo wszystkie inne wyrażenia dostępne w Pythonie 3 i Pythonie 2.7 to po prostu cukier syntaktyczny wokół wyrażenia generatora. Zestaw pojęć:
>>> {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}
Rozumienie ze zrozumieniem:
>>> 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}
I listy składanych w Pythonie 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]
W Pythonie 2 listy składane to nie tylko cukier składniowy. Ale jedyna różnica polega na tym, że x pod Pythonem 2 przecieka do przestrzeni nazw.
>>> x
9
Będąc pod Pythonem 3, otrzymasz
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Oznacza to, że najlepszym sposobem na uzyskanie ładnego wydruku zawartości wyrażenia generatora w Pythonie jest zrobienie z niego zrozumienia listy! Jednak to oczywiście nie zadziała, jeśli masz już obiekt generatora. Spowoduje to utworzenie listy jednego generatora:
>>> foo = (x*x for x in range(10))
>>> [foo]
[<generator object <genexpr> at 0xb7559504>]
W takim przypadku będziesz musiał zadzwonić list():
>>> list(foo)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Chociaż to działa, ale jest trochę głupie:
>>> [x for x in foo]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]