Jak korzystać z generatorów w Pythonie (oświadczenie o wydajności)

Naucz się pisać generatory w Pythonie. Zrozum słowo kluczowe „profit”, leniwą ocenę, optymalizację pamięci i porównaj generatory ze strukturami list.

Wypróbuj to rozwiązanie w Edytorze

Przegląd

Podczas pracy z ogromnymi zbiorami danych, plikami dziennika lub nieskończonymi strumieniami danych jednoczesne ładowanie wszystkich elementów do pamięci (np. zwracanie dużej listy) może łatwo wyczerpać systemową pamięć RAM i spowodować awarię aplikacji. Python oferuje genialne, oszczędzające pamięć rozwiązanie: generatory.

Generator to specjalny typ funkcji, który zwraca leniwy iterator. Zamiast obliczać wszystkie wartości na raz i zwracać je, generator generuje wartości pojedynczo, zgodnie z żądaniem. Kluczową różnicą jest stwierdzenie „yield”. Kiedy funkcja generatora wywołuje „yield”, wstrzymuje stan wykonania (zmienne, wskaźnik instrukcji) i zwraca uzyskaną wartość. Gdy zostanie zażądana następna wartość, funkcja wznawia działanie dokładnie w miejscu, w którym została wstrzymana.

Ponieważ obliczenia generatora są wykonywane leniwie, zużywają one prawie zero pamięci niezależnie od rozmiaru zestawu danych. Python obsługuje także wyrażenia generatora, które używają składni w nawiasach „(x dla x w danych)” w celu tworzenia lekkich generatorów wbudowanych bez deklarowania pełnych funkcji.

Dane wyjściowe kodu i wykonania

Ten skrypt demonstruje generowanie sekwencji przy użyciu funkcji generatora z instrukcją plon i wyrażeniami generatora.

generators_demo.py
Spróbuj w Edytorze
# 1. Generator function using yield
def count_up_to(limit):
    count = 1
    while count <= limit:
        yield count
        count += 1

# Instantiating the generator
counter = count_up_to(3)
print("Memory safe generator instantiated.")

# Fetching values manually
print("Next 1:", next(counter))
print("Next 2:", next(counter))
print("Next 3:", next(counter))

# 2. Iterating with a for loop (automatically handles StopIteration)
print("\n--- Looping over generator ---")
for num in count_up_to(4):
    print("Num:", num)

# 3. Generator expression (Shorthand syntax)
squares_gen = (x**2 for x in range(1, 4))
print("\nGenerator expression elements:")
print(list(squares_gen)) # Cast to list to print all elements
Wyjście terminala
Memory safe generator instantiated.
Next 1: 1
Next 2: 2
Next 3: 3

--- Looping over generator ---
Num: 1
Num: 2
Num: 3
Num: 4

Generator expression elements:
[1, 4, 9]

Wdrażanie krok po kroku

  • Zdefiniuj funkcję za pomocą standardowego słowa kluczowego def.
  • Użyj słowa kluczowego return zamiast return, aby przekazać wartości z powrotem do strumienia iteratora.
  • Wykonaj iterację po generatorze za pomocą pętli for lub wywołaj wbudowaną funkcję next(gen) w celu wyodrębnienia wartości.
  • Użyj wyrażeń generatora (używając nawiasów) do prostych, wbudowanych, leniwych konwersji.

Często zadawane pytania

Jaka jest główna przewaga generatorów nad listami?

Wydajność pamięci. Listy przechowują wszystkie elementy w pamięci RAM jednocześnie, a generatory wyświetlają elementy jeden po drugim na żądanie, umożliwiając przetwarzanie zbiorów danych większych niż całkowita pamięć systemu.

Co się stanie, gdy w generatorze skończą się przedmioty?

Python zgłasza wyjątek StopIteration. Pętla for automatycznie wychwytuje ten wyjątek, aby bezpiecznie zakończyć pętlę, ale ręczne wywołanie funkcji next() na wyczerpanym generatorze spowoduje zgłoszenie wyjątku.

Powiązane tematy

Polecane zasoby Pythona

Poszerzaj swoją wiedzę dzięki powiązanym interaktywnym samouczkom, ściągawkom i porównaniom kodów.