Що таке генератор і ключове слово yield

4 хв. читання

Щоб зрозуміти, що робить yield, необхідно знати, що таке генератори, а перед генераторами йдуть ітератори.

Ітератори

Коли ви створюєте список, ви можете прочитати його елементи один за одним. Це називається ітерація:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

В даному випадку, mylist є ітерованим об'єктом. При створенні списку за допомогою спискових виразів, він також буде ітерованим.

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

Все, до чого можна застосувати for … in … : є ітерованими об'єктами: lists, strings, files

Ітерації зручно використовувати, тому що, ви можете прочитати дані багато разів, але вони зберігаються в пам'яті й інколи це призводить до зайвих затрат ресурсів.

Генератори

Генератори це ті ж самі ітератори, але дані ви можете проітерувати лише один раз. Це тому, що вони не зберігаються в пам'яті, а генеруються на льоту:

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4
>>> for i in mygenerator:
...    print(i)

>>> 

Генератори використовують такий же синтаксис, як і спискові вирази, окрім дужок: ( ) замість [ ]. Ви не можете виконати for i in mygenerator вдруге, оскільки генератор може бути використаний лише раз: він вираховує 0, тоді видаляє його з пам'яті і обчислює 1, видаляє його, обчислює 4 і також його видаляє, один за одним.

Yield

Yield це ключове слово, що використовується подібно до return, однак замість функції виступає генератор.

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # створюємо генератор
>>> print(mygenerator) # mygenerator - об'єкт!
<generator 0xb7555c34="" at="" creategenerator="" object="">
>>> for i in mygenerator:
...     print(i)
0
1
4

Цей приклад недоцільний, але він чудово демонструє зручність використання, коли вам необхідно лише прочитати дані, які повертає функція.

Щоб опанувати yield, ви повинні зрозуміти, що, коли ви викликаєте функцію, код, написаний в тілі функції не виконується. Функція лише повертає об'єкт генератора.

Ваш код буде викликатися кожного разу, коли for буде звертатися до генератора.

Тепер найважче:

Коли for перший раз викликає об'єкт генератора з функції, вона виконає код функції від початку і до слова yield - тоді поверне перше значення ітерації. Кожен наступний виклик буде відбуватися ще одна ітерація циклу і буде повертатися наступне значення. І так поки не закінчаться значення.

Генератор вважається порожнім, як тільки при виконанні коду не зустрінеться yield. Причиною може бути кінець циклу, або не виконання умови if … else

Itertools – ваш кращий друг

Модуль Itertools містить спеціальні функції для управління ітерованими об'єктами. Можливо бажаєте продублювати генератор? З'єднати два генератори? Згрупувати значення вкладених списків в одну лінію?

Тоді import itertools.

Для прикладу, можливі результати кінних гонок з 4 кіньми:

>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)
<itertools.permutations 0xb754f1dc="" at="" object="">
>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
 (1, 2, 4, 3),
 (1, 3, 2, 4),
 (1, 3, 4, 2),
 (1, 4, 2, 3),
 (1, 4, 3, 2),
 (2, 1, 3, 4),
 (2, 1, 4, 3),
 (2, 3, 1, 4),
 (2, 3, 4, 1),
 (2, 4, 1, 3),
 (2, 4, 3, 1),
 (3, 1, 2, 4),
 (3, 1, 4, 2),
 (3, 2, 1, 4),
 (3, 2, 4, 1),
 (3, 4, 1, 2),
 (3, 4, 2, 1),
 (4, 1, 2, 3),
 (4, 1, 3, 2),
 (4, 2, 1, 3),
 (4, 2, 3, 1),
 (4, 3, 1, 2),
 (4, 3, 2, 1)]
```</itertools.permutations></generator>
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація