Python, ітератори, генератори, шпаргалка

Python, ітератори, генератори, шпаргалка.

Під катом шпаргалка, в якій дуже коротко описано навіщо і як створювати та використовувати генератори.

Найбільш поширений тип циклу в пітоні такий:

У цьому скрипті як "iterator object" може виступати список, словник, відкритий файл, загалом будь-який ітератор.

Припустимо, ми хочемо опрацювати набір якихось даних. Зазвичай схема дій така:

  • Створюємо список, елементами якого є дані, які потрібно обробити.
  • Обробляємо елементи списку у циклі "for. in"

Але не завжди зручно діяти за такою схемою. Наприклад, зустрілася одна з таких ситуацій:

  • Дуже великий набір даних. Працюватиме, але при цьому займе багато часу та оперативної пам'яті.
  • Великий час отримання одного елемента набору. Доведеться чекати, поки отримаємо всі дані набору, іноді це може зайняти чималий час. Припустимо, нам потрібно лише кілька перших значень великого набору, а ми отримуємо чи обчислюємо всі значення.

У разі добре було б обчислювати чергове значення лише тоді, коли вона нам знадобиться, а чи не обчислювати все значення заздалегідь. Це можна здійснити трьома шляхами:

  1. Створити об'єкт-ітератор.
  2. Створити функцію-генератор.
  3. Використовувати генераторний вираз.

Додано до Python 2.2

Щоб отримати об'єкт-ітератор, потрібно створити об'єкт, який матиме два методи зі спеціальними іменами:

  • __iter__() – метод, який повертає сам об'єкт.
  • next() - метод, який повертає таке значення ітератора.

Приклад ітератора

Припустимо, що намНеобхідно створити об'єкт, який бере дані з рядків дуже великого файла. Дані потрібні порціями, записані в рядках текстового файлу, одна порція, один рядок. Обробляти потрібно у циклі "for. in"

Створюємо такий клас:

Усередині все просто. Головна робота у методі next(). У ньому зчитується наступний рядок файлу, обробляється (число множиться на 2) та повертається в операторі return(). Коли файл закінчиться буде викликано винятокStopIteration.

Генератори

Додано до Python 2.2/2.3

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

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

По суті, це ключове слово створює ітератор, просто створення ітератора спрощується за рахунок того, що методи__iter__()іnext()створюються автоматично. При виході з функції не операторомyieldавтоматично генеруєтьсяStopIteration.

Приклад створення генератора

Створити функцію генератора дуже легко. Пишемо функцію, яка повертає в операторіyieldдані.

Як бачимо,yieldвикликається усередині циклу. Рядки 2 і 5 вставлені для того, щоб продемонструвати те, що в цих місцях код викликатиметься одноразово. Рядок 2 при першому виклику функції, рядок 5 – при останньому виклику.

Генераторні вирази

Додано до Python 2.4

Іноді, у простих випадках, можна не писати функцію-генератор, аобійтисягенераторним виразом. Це такий синтаксис для створення простого генератора у тому місці, де це потрібно.

Де потрібно врахувати таке:

  • Вираз завжди поміщений у круглі дужки.
  • У випадку, якщо вираз використовується як єдиний аргумент при виклику функції, круглі дужки виразу можуть збігатися з круглими дужками виклику функції.
  • expr2 - ітератор, що генерує значення.
  • expr1 - операція, яка проводиться зі згенерованим expr2 значенням.

Таким чином, генераторний вираз працює наступним чином:

  1. При черговому викликі expr2 і генерує наступне вихідне значення.
  2. Сгенероване вихідне значення підставляється expr1.
  3. Згенероване expr1 значення повертається генераторним виразом.
  4. Генераторний вираз чекає на наступний виклик

Вираз надрукує квадрати чисел 1,5,8

Вираз надрукує суму результатів обчислення виразу x * (5 + x), при x приймає цілочислові значення від 10 до 20,