Насправді дуже крута штука, використавши яку тебе зауважає тімлід 😎

Що це та навіщо?

Генератор — це функція з yield або вираз (comprehension), що вертає ітератор (те, по чому можна пройтись циклом)

Генетори дуже корисні, коли нам не потрібно усі дані одразу, або ці дані генеруються динамічно

Найпростійший приклад — range([start], stop) - це генератор, що продукує послідовно цілі числа, починаючи з числа start, і зупиниться перед stop. Пам’ять пристрою буде використана лише для поточного числа в циклі, а не для мільйону чисел — чудове заощадження пам’яті 🤩

Як це виглядає?

generator_comprehension = (i**2 for i in range(10))

def generator_function(n):
    for i in range(n):
        yield i ** 2

generator = generator_function(10)

# Використання

# Цей код може бути використаним лише раз, бо генератор вичерпав свої значення
for j in generator:
    print(j)
for k in generator_comprehension:
    print(k)

# А цей можна повторювати вічно
for l in generator_function(100):
    print(l)

Виглядає просто, але водночас є гнучкішим та ефективнішим, ніж код нижче

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

# Цей код створить масив на 100 чисел
for j in common_function(100):
    print(j)

squared_numbers = common_function(100)
# Цей код теж можна повторювати вічно, бо масив давно в пам'яті
# Але зазвичай ми так не пишемо
for k in squared_numbers:
    print(k)

А можна реальний приклад?

Так, і хорошим прикладом тут буде — зрівняння/сплощення списку списків (flattening list):

def flatten(nested_list):
    for item in nested_list:
        if isinstance(item, list):
            yield from flatten(item)
        else:
            yield item

# Використання:
nested_list = [1, [2, [3, 4], 5], 6], [7, 8]]
flattened_list = list(flatten(nested_list))
# Результат: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Тобто, при будь-якій вкладеності списків в результаті у нас буде лише один список

Тут можна помітити рекурсію, але під час виконання функції, насправді не забирається зайва пам'ять, бо yield from фактично передає контроль над генерацією даних — новому генератору

Q&A

Якщо у вас все ще залишились запитання про генератори у пайтоні — завжди готовий відповісти у коментарях, а якщо про щось інше — теж пишіть, може зроблю з цього нову статтю

Усім добра та мирного неба над головою ❤️

Додаткові матеріали

Багато про генератори та корутини (предок async)

Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Вітя
Вітя@kor0p

Python SDET @ ajax.systems

813Прочитань
10Автори
17Читачі
Підтримати
На Друкарні з 14 квітня

Більше від автора

Вам також сподобається

  • Hello, RabbitMQ на PHP

    Реалізуємо найпростіший приклад взаємодії з брокером повідомлень за 10 хвилин.

    Теми цього довгочиту:

    Rabbitmq
  • Mash Script: Рядки, string

    Стаття охоплює різні аспекти роботи з рядками в мові Mash Script, включаючи їхній літеральний запис, методи, рядки-шаблони та інше.

    Теми цього довгочиту:

    Mash Script

Коментарі (2)

Як працює “from”, який стоїть після “yield”?

Вам також сподобається

  • Hello, RabbitMQ на PHP

    Реалізуємо найпростіший приклад взаємодії з брокером повідомлень за 10 хвилин.

    Теми цього довгочиту:

    Rabbitmq
  • Mash Script: Рядки, string

    Стаття охоплює різні аспекти роботи з рядками в мові Mash Script, включаючи їхній літеральний запис, методи, рядки-шаблони та інше.

    Теми цього довгочиту:

    Mash Script