JuniorКодИногдаЕщё не отвечали
Реализуйте свой reversed генератором и итератором
Реализуйте my_reversed(seq), выдающий элементы индексируемой последовательности с конца к началу, не вызывая встроенный reversed.
Требования:
(__iter__ / __next__).
- Дайте версию генераторной функцией и класс, реализующий протокол итератора
- Не стройте развёрнутую копию всей последовательности заранее.
def my_reversed(seq):
# ваш код здесь
Допишите реализацию.
Генератором: пройдите индекс от len(seq)-1 до 0 и yield seq[i] — лениво, по одному элементу. Классом-итератором: сохраните последовательность и индекс current в __init__, верните self из __iter__, а в __next__ уменьшайте индекс и возвращайте элемент, бросая StopIteration при достижении 0. Оба эквивалентны; генератор просто короче.
- ✗Опускать
__iter__, возвращающийself, из-за чего объект не работает вfor - ✗Забывать бросать
StopIteration, когда индекс исчерпан - ✗Материализовать развёрнутую копию вместо ленивой выдачи по индексу
- →Почему
__iter__должен возвращатьself, чтобы итератор работал вfor? - →Что сигнализирует
StopIterationи кто его ловит?
Оглавление
Задача
Реализуйте my_reversed: выдавайте элементы последовательности с конца к началу — генератором и классом-итератором.
Решение
def my_reversed(seq):
for i in range(len(seq) - 1, -1, -1):
yield seq[i]
class MyReversed:
def __init__(self, seq):
self.seq = seq
self.current = len(seq)
def __iter__(self):
return self
def __next__(self):
if self.current == 0:
raise StopIteration
self.current -= 1
return self.seq[self.current]
Ключевые моменты
- Генератор ленив:
yieldотдаёт по одному элементу при каждомnext(). - Класс реализует протокол:
__iter__возвращаетself,__next__бросаетStopIteration. - Обе версии эквивалентны — генератор лишь компактнее.
Оглавление