Yield - ключове слово, яке використовується для виходу з функції-генератора значень списку. Подібні функції-генератори використовуються, коли вам потрібно створювати якусь складнішу послідовність, ніж повертається range (10).
Для розуміння, що робить yield, необхідно розуміти, що таке генератори. Генераторів ж передують ітератори. Коли ви створюєте список, ви можете зчитувати його елементи один за іншим - це називається итерацией:
Mylist є ітеріруемим об'єктом. Коли ви створюєте список, використовуючи генераторное вираз, ви створюєте також итератор:
Все, до чого можна застосувати конструкцію «for ... in ...», є ітеріруемим об'єктом: списки, рядки, файли ... Це зручно, тому що можна зчитувати з них значення скільки буде потрібно - проте все значення зберігаються в пам'яті, а це не завжди бажано, якщо у вас багато значень.
Генератори Python
Генератори це теж ітеріруемие об'єкти, але прочитати їх можна лише один раз. Це пов'язано з тим, що вони не зберігають значення в пам'яті, а генерують їх на льоту:
Все те ж саме, хіба що використовуються круглі дужки замість квадратних. АЛЕ: не можна застосувати конструкцію for i in mygenerator вдруге, так як генератор може бути використаний тільки один раз: він обчислює 0, потім забуває про нього і обчислює 1, завершується обчисленням 4 - одне за іншим.
Yield це ключове слово, яке використовується як return для функції, яка поверне генератор.
В даному випадку приклад даремний, але це зручно, якщо ви знаєте, що функція поверне великий набір значень, який треба буде прочитати тільки один раз.
Щоб освоїти yield, ви повинні розуміти, що коли ви викликаєте функцію, код всередині тіла функції не виконується. Функція тільки повертає об'єкт-генератор - трохи мудро :-)
Ваш код буде викликатися кожен раз, коли for звертається до генератора.
Тепер важка частина:
У перший запуск вашої функції, вона буде виконуватися від початку до того моменту, коли вона наткнеться на yield - тоді вона поверне перше значення з циклу. На кожен наступний виклик буде відбуватися ще одна ітерація написаного вами циклу, повертатися буде таке значення - і так поки значення не закінчаться.
Генератор вважається порожнім, як тільки при виконанні коду функції не зустрічається yield. Це може статися через кінця циклу, або ж якщо не виконується якесь із умов «if / else».
Метод extend () це метод об'єкта списку, який очікує на вхід що-небудь ітеріруемое і додає його значення до списку.
Зазвичай ми передаємо йому список:
Але в нашому коді він приймає генератор, що добре з наступних причин:
І це працює, тому що Python все одно, є аргумент цього методу списком чи ні. Python чекає ітеріруемий об'єкт, так що це спрацює з рядками, списками, кортежами і генераторами! Це називається качиної типізацією і є однією з причин, чому Python так крутий.