Iterators: Difference between revisions
Content added Content deleted
m (→{{header|J}}) |
(A Python implementation) |
||
Line 436: | Line 436: | ||
Saturday Wednesday Tuesday |
Saturday Wednesday Tuesday |
||
Purple Yellow Orange |
Purple Yellow Orange |
||
</pre> |
|||
=={{header|Python}}== |
|||
Python's built-in containers (list, dict, collections.deque, etc.) are ''iterable''. When an iterable object is used in a <code>for</code> loop, a new ''iterator'' is created automatically. Alternatively, the built-in <code>iter()</code> function can be used to obtain an iterator for an iterable, allowing us to single step through it's members using <code>next()</code>. When an iterator has been exhausted, calls to <code>next()</code> will raise a <code>StopIteration</code> exception. |
|||
We can create our own iterators by implementing the ''iterator protocol''. The iterator protocol requires us to implement an <code>__iter__</code> method and a <code>__next__</code> method, as demonstrated by the <code>MyIterable</code> and <code>MyIterator</code> classes below. |
|||
<lang python>"""Iterables and iterators. Requires Python >= 3.6 for type hints.""" |
|||
from collections import deque |
|||
from typing import Iterable |
|||
from typing import Iterator |
|||
from typing import Reversible |
|||
# array-like |
|||
days = [ |
|||
"Monday", |
|||
"Tuesday", |
|||
"Wednesday", |
|||
"Thursday", |
|||
"Friday", |
|||
"Saturday", |
|||
"Sunday", |
|||
] |
|||
# deque is implemented as a doubly linked list |
|||
colors = deque( |
|||
[ |
|||
"red", |
|||
"yellow", |
|||
"pink", |
|||
"green", |
|||
"purple", |
|||
"orange", |
|||
"blue", |
|||
] |
|||
) |
|||
class MyIterable: |
|||
class MyIterator: |
|||
def __init__(self) -> None: |
|||
self._day = -1 |
|||
def __iter__(self): |
|||
return self |
|||
def __next__(self): |
|||
if self._day >= 6: |
|||
raise StopIteration |
|||
self._day += 1 |
|||
return days[self._day] |
|||
class MyReversedIterator: |
|||
def __init__(self) -> None: |
|||
self._day = 7 |
|||
def __iter__(self): |
|||
return self |
|||
def __next__(self): |
|||
if self._day <= 0: |
|||
raise StopIteration |
|||
self._day -= 1 |
|||
return days[self._day] |
|||
def __iter__(self): |
|||
return self.MyIterator() |
|||
def __reversed__(self): |
|||
return self.MyReversedIterator() |
|||
def print_elements(container: Iterable[object]) -> None: |
|||
for element in container: |
|||
print(element, end=" ") |
|||
print("") # for trailing newline |
|||
def _drop(it: Iterator[object], n: int) -> None: |
|||
"""Helper function to advance the iterator at most `n` times.""" |
|||
try: |
|||
for _ in range(n): |
|||
next(it) |
|||
except StopIteration: |
|||
pass |
|||
def print_first_fourth_fifth(container: Iterable[object]) -> None: |
|||
# Get an iterator from the iterable |
|||
it = iter(container) |
|||
print(next(it), end=" ") |
|||
_drop(it, 2) |
|||
print(next(it), end=" ") |
|||
print(next(it)) |
|||
def print_reversed_first_fourth_fifth(container: Reversible[object]) -> None: |
|||
# Reverse iterator |
|||
it = reversed(container) |
|||
print(next(it), end=" ") |
|||
_drop(it, 2) |
|||
print(next(it), end=" ") |
|||
print(next(it)) |
|||
def main() -> None: |
|||
my_iterable = MyIterable() |
|||
print("All elements:") |
|||
print_elements(days) |
|||
print_elements(colors) |
|||
print_elements(my_iterable) |
|||
print("\nFirst, fourth, fifth:") |
|||
print_first_fourth_fifth(days) |
|||
print_first_fourth_fifth(colors) |
|||
print_first_fourth_fifth(my_iterable) |
|||
print("\nLast, fourth to last, fifth to last:") |
|||
print_reversed_first_fourth_fifth(days) |
|||
print_reversed_first_fourth_fifth(colors) |
|||
print_reversed_first_fourth_fifth(my_iterable) |
|||
if __name__ == "__main__": |
|||
main() |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
All elements: |
|||
Monday Tuesday Wednesday Thursday Friday Saturday Sunday |
|||
red yellow pink green purple orange blue |
|||
Monday Tuesday Wednesday Thursday Friday Saturday Sunday |
|||
First, fourth, fifth: |
|||
Monday Thursday Friday |
|||
red green purple |
|||
Monday Thursday Friday |
|||
Last, fourth to last, fifth to last: |
|||
Sunday Thursday Wednesday |
|||
blue green pink |
|||
Sunday Thursday Wednesday |
|||
</pre> |
</pre> |
||