508
Rozdział 12.
Wygeneruj swoje dane
Nawiasy okrągłe wokół kodu = generator
Jeśli natrafiasz na coś, co wygląda jak komprehencja listy, lecz jest ujęte w nawiasy okrągłe,
masz do czynienia z
generatorem
.
for i in (x*3 for x in [1,2,3,4,5]):
print(i)
Generator może być używany wszędzie
tam, gdzie używana jest komprehencja
listy, generuje również te same wyniki
co ona.
To wygląda jak
komprehencja listy,
ale nią nie jest; jest
za to generatorem.
Jak widać to na końcu poprzedniej strony, jeśli nawiasy kwadratowe obejmujące komprehencję listy
zastąpisz nawiasami okrągłymi, otrzymasz te same wyniki; oznacza to, że generator i komprehencja
listy generują te same dane.
Nie są jednak wykonywane w ten sam sposób.
Jeśli zastanawiasz się teraz nad ostatnim zdaniem, weź pod uwagę to, że gdy wykonywana jest
komprehencja listy,
wszystkie
jej dane generowane są przed jakimkolwiek innym przetwarzaniem. Jeśli
odniesiemy to do przykładu przedstawionego na początku tej strony, będzie to znaczyło, że pętla
for
nie
rozpocznie przetwarzania
żadnych danych wytworzonych przez komprehencję listy, dopóki ta ostatnia
nie zostanie ukończona. Oznacza to, że komprehencja listy, która generuje swoje dane przez długi czas,
powoduje opóźnienie wykonania wszelkiego innego kodu aż do momentu,
gdy zostanie zakończona.
W przypadku tej niewielkiej listy elementów danych (która została pokazana powyżej) nie stanowi
to wielkiego problemu.
Wyobraź sobie jednak, że Twoja komprehencja listy ma tworzyć listę generującą 10 milionów elementów
danych. Masz w takiej sytuacji do czynienia z dwoma problemami: po pierwsze, musisz czekać aż
komprehencja listy przetworzy 10 milionów elementów danych,
zanim będziesz mógł zrobić coś innego,
a po drugie, musisz martwić się o to, czy komputer, na którym uruchamiasz swój kod, ma wystarczająco
dużo pamięci operacyjnej, aby zmieścić w niej wszystkie dane niezbędne do wykonania komprehencji
(
10 milionów
oddzielnych kawałków danych). Gdy Twoja komprehencja listy wyczerpie dostępną dla
niej pamięć operacyjną, interpreter przerwie swoje działanie (a Twój program pójdzie z dymem).
Generatory wytwarzają elementy danych po jednym naraz...
Gdy zastąpisz nawiasy kwadratowe swojej komprehencji listy nawiasami okrągłymi, komprehencja ta
stanie się
generatorem
, a Twój kod zacznie zachowywać się inaczej.
W przeciwieństwie do komprehencji list, które muszą się zakończyć, zanim będzie mógł zostać wykonany
jakikolwiek inny kod, generator zwraca dane od razu po ich wytworzeniu. Oznacza to, że gdy będziesz
generował 10 milionów elementów danych, interpreter będzie potrzebował tylko tyle pamięci, aby
umieścić
jeden
element (naraz), a jakikolwiek kod oczekujący na konsumpcję elementów danych
tworzonych przez generator będzie mógł być wykonany natychmiast. A więc
nie ma tu żadnego czekania.
Różnicy, jaką może zrobić zastosowanie generatora, nie da się wyjaśnić w lepszy sposób niż za
pomocą przykładu, dlatego wykonajmy pewne proste zadanie dwukrotnie: najpierw za pomocą
komprehencji listy, a potem przy użyciu generatora.
Komprehencje
list i generatory
wytwarzają te
same wyniki, ale
działają w zupełnie
inny sposób.

Get Python Rusz głową! Wydanie II now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.