JuniorCodeOccasionalNot answered yet
Implement your own reversed as a generator and an iterator
Implement my_reversed(seq) that yields the elements of an indexable sequence back to front, without calling the built-in reversed.
Requirements:
iterator protocol (__iter__ / __next__).
- Provide both a generator-function version and a class implementing the
- Do not build a reversed copy of the whole sequence up front.
def my_reversed(seq):
# your code here
Write the implementation.
As a generator, loop the index from len(seq)-1 down to 0 and yield seq[i] — lazy, one element at a time. As an iterator class, store the sequence and a current index in __init__, return self from __iter__, and in __next__ decrement the index and return the element, raising StopIteration when it reaches 0. Both are equivalent; the generator is just shorter.
- ✗Omitting
__iter__returningself, so the object isn't usable in aforloop - ✗Forgetting to raise
StopIterationwhen the index is exhausted - ✗Materializing a reversed copy instead of yielding lazily by index
- →Why must
__iter__returnselffor the iterator to work in aforloop? - →What does
StopIterationsignal, and who catches it?
Contents
Task
Implement my_reversed: yield a sequence's elements back to front — as a generator and as an iterator class.
Solution
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]
Key points
- The generator is lazy:
yieldreturns one element pernext()call. - The class implements the protocol:
__iter__returnsself,__next__raisesStopIteration. - Both versions are equivalent — the generator is just more compact.
Contents