0Pricing
Python Academy · Lekcja

Funkcje generatorów

Generuj wartości leniwie za pomocą yield

Funkcje generatorów to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Czym jest generator

Funkcja generatora wygląda jak zwykła funkcja, ale używa yield zamiast return lub razem z nim. Jej wywołanie nie uruchamia treści funkcji — zwraca obiekt generatora, który jest iteratorem.

def gen():
    yield 1
    yield 2
    yield 3

g = gen()
print(type(g).__name__)
print(list(g))

yield wstrzymuje wykonanie

Za każdym razem, gdy wywołasz next(), funkcja wykonuje się do napotkania yield, zwraca tę wartość i zamraża swój stan. Następne wywołanie wznawia działanie bezpośrednio za yield.

def steps():
    print('start')
    yield 'a'
    print('resumed')
    yield 'b'

g = steps()
print(next(g))
print(next(g))

Iterowanie po generatorze

Ponieważ generator jest iteratorem, pętla for automatycznie nim steruje i zatrzymuje się, gdy funkcja się kończy (co wewnętrznie powoduje wystąpienie StopIteration).

def countdown(n):
    while n > 0:
        yield n
        n -= 1

for x in countdown(4):
    print(x)

Leniwe wartościowanie

Generatory działają leniwie: wartości są tworzone dopiero na żądanie. Dzięki temu można reprezentować bardzo duże lub nieskończone sekwencje bez zajmowania dużej ilości pamięci.

def naturals():
    n = 1
    while True:
        yield n
        n += 1

g = naturals()
print(next(g), next(g), next(g))

Stan między wywołaniami yield

Zmienne lokalne zachowują swoje wartości między punktami yield. Generator naturalnie pamięta miejsce, w którym zakończył działanie, więc nie trzeba ręcznie śledzić indeksu.

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

g = fib()
print([next(g) for _ in range(7)])

Generatory a tworzenie listy

Zwykła funkcja tworzy i zwraca całą listę jednocześnie. Generator zwraca elementy na żądanie. Należy użyć generatora, gdy sekwencja jest duża lub działanie może zostać wcześniej przerwane.

def squares_list(n):
    result = []
    for i in range(n):
        result.append(i * i)
    return result

def squares_gen(n):
    for i in range(n):
        yield i * i

print(squares_list(5))
print(list(squares_gen(5)))

Wcześniejsze zatrzymanie

Ponieważ elementy są tworzone leniwie, można wyjść z pętli, a generator po prostu nie obliczy pozostałych elementów.

def naturals():
    n = 1
    while True:
        print('producing', n)
        yield n
        n += 1

for x in naturals():
    if x > 3:
        break
    print('got', x)

return wewnątrz generatora

Puste return w generatorze po prostu go kończy (powodując wystąpienie StopIteration). Każda zwrócona wartość staje się atrybutem value wyjątku, który większość pętli ignoruje.

def up_to(stop):
    i = 0
    while True:
        if i >= stop:
            return
        yield i
        i += 1

print(list(up_to(4)))

Generatory są jednorazowe

Tak jak wszystkich iteratorów, generatora można użyć tylko raz. Po wyczerpaniu nie zwraca już żadnych wartości. Aby otrzymać nowy generator, należy ponownie wywołać funkcję.

def gen():
    yield 1
    yield 2

g = gen()
print(list(g))
print(list(g))
print(list(gen()))

Filtrowanie za pomocą generatorów

Generatory umożliwiają tworzenie przejrzystych potoków przetwarzania danych. W tym przykładzie zwracamy tylko liczby parzyste, po jednej na raz.

def evens(numbers):
    for n in numbers:
        if n % 2 == 0:
            yield n

print(list(evens(range(10))))

Łączenie generatorów

Generator może pobierać dane z innego generatora, tworząc wieloetapowy potok, w którym każdy etap działa leniwie.

def numbers(n):
    for i in range(n):
        yield i

def doubled(src):
    for x in src:
        yield x * 2

print(list(doubled(numbers(5))))

Szybkie sprawdzenie

Sprawdź swoją znajomość funkcji generatorów.

Podsumowanie

Poznałeś(-aś) funkcje generatorów:

  • yield wstrzymuje i wznawia wykonanie, zachowując stan lokalny.
  • Wywołanie funkcji zwraca leniwy obiekt generatora.
  • Generatory są oszczędne pamięciowo i świetnie sprawdzają się w potokach oraz nieskończonych strumieniach.
  • Można ich użyć tylko raz, tak jak każdego iteratora.

Następnie poznasz jeszcze bardziej zwięzłe wyrażenia generatorowe.

Często zadawane pytania

Czy lekcja „Funkcje generatorów” jest bezpłatna?

Tak — pełny tekst „Funkcje generatorów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Funkcje generatorów”?

Generuj wartości leniwie za pomocą yield Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Funkcje generatorów”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Protokół iteratora
  2. Funkcje generatorów
  3. Wyrażenia generatorowe
  4. yield from i delegowanie
← Powrót do Python Academy