Skip to content

Commit fe5f229

Browse files
committed
📝 Added 28-iterators.md
1 parent 19d4d96 commit fe5f229

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed

28-iterators.md

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# Python Iterators and Iterables
2+
3+
**Video link:**
4+
5+
In this video, we learned about iterables and iterators in Python with the help of examples.
6+
7+
**Programs in the Video**
8+
9+
- [Python Iterables](#python-iterables)
10+
- [Python Iterators](#python-iterators)
11+
- [The `__next__()` method](#the-__next__-method)
12+
- [Working of `for` loops](#working-of-for-loops)
13+
- [Creating Custom Iterators](#creating-custom-iterators)
14+
15+
---
16+
17+
## Python Iterables
18+
Anything that you can loop over in Python is called an iterable. For example, a list is an iterable.
19+
For an object to be considered an iterable, it must have the `__iter()__` method.
20+
21+
```python
22+
numbers = [1, 4, 9]
23+
print(dir(numbers))
24+
```
25+
26+
**Output**
27+
```
28+
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__',
29+
'__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__',
30+
'__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__',
31+
'__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend',
32+
'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
33+
```
34+
35+
We can see that there is a special `__iter__()` method among all these methods. Let's call this method.
36+
37+
```python
38+
numbers = [1, 4, 9]
39+
40+
value = numbers.__iter__()
41+
print(value)
42+
```
43+
44+
**Output**
45+
```
46+
<list_iterator object at 0x7fa223878d00>
47+
```
48+
49+
The `iter` method returns an iterator object.
50+
51+
---
52+
53+
## Python Iterators
54+
55+
Iterator in Python is simply an object that can return data one at a time while iterating over it.
56+
57+
For an object to be an iterator, it must implement two methods:
58+
- `__iter__()`
59+
- `__next__()`
60+
61+
These are collectively called the iterator protocol.
62+
63+
---
64+
65+
## The __next__() method
66+
67+
The `__next__()` method returns the next value in the iteration.
68+
69+
```python
70+
numbers = [1, 4, 9]
71+
value = numbers.__iter__()
72+
73+
item1 = value.__next__()
74+
print(item1)
75+
```
76+
77+
**Output**
78+
```
79+
1
80+
```
81+
82+
Now, if we run the `next` method again, it should return the next item which is `4`. It's because the `next` method also updates the state of the iterator.
83+
84+
85+
```python
86+
numbers = [1, 4, 9]
87+
value = numbers.__iter__()
88+
89+
item1 = value.__next__()
90+
print(item1)
91+
92+
item2 = value.__next__()
93+
print(item2)
94+
95+
item3 = value.__next__()
96+
print(item3)
97+
```
98+
99+
**Output**
100+
```
101+
1
102+
4
103+
9
104+
```
105+
106+
>**Note**: Instead of calling these special methods with an underscore,
107+
>Python has an elegant way to call `__iter__()` simply with the `iter()` function and `__next__()` with the `next()` function.
108+
109+
Here, we have already reached the end of our list. Now, let's see what happens if we further try to get the next value.
110+
111+
```python
112+
numbers = [1, 4, 9]
113+
value = iter(numbers)
114+
115+
item1 = next(value)
116+
print(item1)
117+
118+
item2 = next(value)
119+
print(item2)
120+
121+
item3 = next(value)
122+
print(item3)
123+
124+
item4 = next(value)
125+
print(item4)
126+
```
127+
128+
**Output**
129+
```
130+
1
131+
4
132+
9
133+
Traceback (most recent call last):
134+
File "<string>", line 13, in <module>
135+
StopIteration
136+
```
137+
138+
Since our list had only 3 elements, the call to the fourth `next()` method raised the `StopIteration` exception.
139+
140+
---
141+
142+
## Working of `for` loops
143+
144+
Did you know that `for` loops internally use the `while` loop to iterate through sequences?
145+
146+
```python
147+
num_list = [1, 4, 9]
148+
149+
iter_obj = iter(num_list)
150+
151+
while True:
152+
try:
153+
element = next(iter_obj)
154+
print(element)
155+
except StopIteration:
156+
break
157+
```
158+
159+
**Output**
160+
```
161+
1
162+
4
163+
9
164+
```
165+
166+
167+
Here's how this code works:
168+
169+
- First, we have created an iterator object from a list using `iter_obj = iter(num_list)`
170+
- Then, we have created an infinite `while` loop.
171+
- Inside the loop, we have used the `next` method to return the next element in the sequence `element = next(iter_obj))` and printed it. We have put this code inside the `try` block.
172+
- When all the items of the iterator are iterated, the `try` block raises the `StopIteration` exception, and the `except` block catches it and breaks the loop.
173+
174+
In fact, this is exactly how `for` loops work behind the scene. A `for` loop internally creates an iterator object, and iterates over it calling the `next` method until a `StopIteration` exception is encountered.
175+
176+
The above code is equivalent to:
177+
```python
178+
num_list = [1, 4, 9]
179+
180+
for element in num_list:
181+
print(element)
182+
```
183+
184+
---
185+
186+
## Creating Custom Iterators
187+
Let's try to make our own iterator object to generate a sequence of even numbers such as 2, 4, 6, 8 and so on.
188+
189+
```python
190+
class Even:
191+
def __init__(self, max):
192+
self.n = 2
193+
self.max = max
194+
195+
def __iter__(self):
196+
return self
197+
198+
def __next__(self):
199+
if self.n <= self.max:
200+
result = self.n
201+
self.n += 2
202+
return result
203+
else:
204+
raise StopIteration
205+
206+
numbers = Even(10)
207+
208+
print(next(numbers))
209+
print(next(numbers))
210+
print(next(numbers))
211+
```
212+
213+
**Output**
214+
```
215+
2
216+
4
217+
6
218+
```
219+
220+
Iterators are powerful tools when dealing with a large stream of data.
221+
If we used regular lists to store these values, our computer would run out of memory.
222+
With iterators, however, we can save resources as they return only one element at a time.
223+
So, in theory, we can deal with infinite data in finite memory.

0 commit comments

Comments
 (0)