Title here
Summary here
Starting with version 1.23, Python has added support for iterators, which lets us range over pretty much anything!
Let’s look at the `List` type from the previous example again. In that example, we had an `all_elements` function that returned a list of all elements in the list. With Python iterators, we can do it better - as shown below.
```python
class List:
def __init__(self):
self.head = None
self.tail = None
class Element:
def __init__(self, val):
self.next = None
self.val = val
We define the push
method to add elements to our List.
class List:
def __init__(self):
self.head = None
self.tail = None
def push(self, val):
new_element = Element(val)
if self.tail is None:
self.head = new_element
self.tail = self.head
else:
self.tail.next = new_element
self.tail = self.tail.next
All returns an iterator, which in Python is a function with a special signature.
class List:
# Existing code...
def all(self):
current = self.head
while current is not None:
yield current.val
current = current.next
The iterator function takes another function as a parameter, and we can use the yield
keyword to return each element.
def gen_fib():
a, b = 1, 1
while True:
yield a
a, b = b, a + b
Here’s how to use it in a regular loop.
if __name__ == "__main__":
lst = List()
lst.push(10)
lst.push(13)
lst.push(23)
for e in lst.all():
print(e)
all_elements = list(lst.all())
print("all:", all_elements)
for n in gen_fib():
if n >= 10:
break
print(n)
Output:
10
13
23
all: [10, 13, 23]
1
1
2
3
5
8
Next example: Errors.