Introduction 🌟
An iterator in Python is an object that allows you to traverse through elements of a collection (like lists, tuples, strings) **one item at a time**. Iterators power loops like for and make lazy evaluation possible.
Note
__iter__() → returns the iterator object itself
__next__() → returns the next value
1. What Is an Iterable? 🧩
An iterable is any object in Python that can return its elements one by one. Examples: list, tuple, set, string, dictionary, generator, file object.
iterable_examples.py
nums = [1, 2, 3]
text = "hello"
print(iter(nums)) # iterable
print(iter(text))2. Getting an Iterator from an Iterable 🔄
get_iterator.py
nums = [10, 20, 30]
it = iter(nums)
print(next(it)) # 10
print(next(it)) # 20
print(next(it)) # 30
# next(it) → StopIterationNote
iter() and next().3. How a for-loop Actually Works 🧠
for_loop_internal.py
nums = [1, 2, 3]
it = iter(nums)
while True:
try:
print(next(it))
except StopIteration:
break✔ This is how Python internally executes a for loop.
4. Creating Your Own Iterator Class 🏗️
custom_iterator.py
class Counter:
def __init__(self, limit):
self.limit = limit
self.current = 1
def __iter__(self):
return self # iterator object
def __next__(self):
if self.current <= self.limit:
value = self.current
self.current += 1
return value
else:
raise StopIteration
c = Counter(5)
for i in c:
print(i)Note
5. Iterator vs Iterable ⚔️
| Iterable | Iterator |
|---|---|
Has __iter__() | Has __iter__() & __next__() |
| Returns iterator | Returns next item |
| Examples: list, tuple | Examples: file, generator |
6. Iterators with Strings 🔤
string_iterator.py
text = "ABC"
it = iter(text)
print(next(it)) # A
print(next(it)) # B
print(next(it)) # C7. Iterators with Dictionaries 🔑
dict_iterator.py
person = {"name": "Sathish", "age": 25}
for key in person:
print(key, person[key])8. Infinite Iterators (itertools) ♾️
infinite_iterator.py
import itertools
counter = itertools.count(1)
print(next(counter))
print(next(counter))
print(next(counter))Note
9. Building a Fibonacci Iterator 🌀
fibonacci_iterator.py
class Fibonacci:
def __init__(self, max_limit):
self.max = max_limit
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
if self.a > self.max:
raise StopIteration
value = self.a
self.a, self.b = self.b, self.a + self.b
return value
for num in Fibonacci(50):
print(num)10. Iterator for Reversing a List 🔁
reverse_iterator.py
class Reverse:
def __init__(self, items):
self.items = items
self.index = len(items)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index -= 1
return self.items[self.index]
for x in Reverse([1, 2, 3, 4]):
print(x)11. Generators vs Iterators ⚡
| Generators | Iterators |
|---|---|
Created with yield | Must define __next__() |
| Simpler syntax | More control |
| Automatically memory-efficient | Depends on implementation |
12. Real-World Uses 🌍
Reading large files efficiently
file_iterator.py
for line in open("data.txt"):
print(line.strip())Processing database results
db_iterator.py
# pseudo-code
cursor = db.execute("SELECT * FROM users")
for row in cursor: # cursor is an iterator
print(row)Streaming API data
api_iterator.py
# pseudo-code
def api_stream():
while True:
yield fetch_data()Conclusion 🎉
You now fully understand Iterators in Python! Want the next topic? Try Decorators, Modules, OOP, or Error Handling. Just tell me! 😊
__iter__ & __next__ — Building Custom IteratorsIntroduction 🌟
In Python, iterators are objects that allow iteration over data one element at a time. To create a custom iterator, you must implement two special methods:
- __iter__(self) → returns the iterator object
- __next__(self) → returns the next value (or raises StopIteration)
Note
for loops, next(), generators, and all iteration tools.1. What is __iter__()? 🔄
The __iter__() method returns the iterator object itself. It is called automatically when iteration begins.
iter_method.py
def __iter__(self):
return self2. What is __next__()? ▶️
The __next__() method returns the next value in the sequence. When the sequence is finished, it must raise StopIteration.
next_method.py
def __next__(self):
if no_more_items:
raise StopIteration
return next_itemNote
3. Creating a Simple Custom Iterator 🧱
simple_iterator.py
class Counter:
def __init__(self, limit):
self.limit = limit
self.current = 1
def __iter__(self):
return self
def __next__(self):
if self.current <= self.limit:
value = self.current
self.current += 1
return value
else:
raise StopIteration
counter = Counter(5)
for num in counter:
print(num)✔️ Prints: 1 2 3 4 5
4. Manually Using iter() and next() 🎮
manual_iter_next.py
numbers = Counter(3)
it = iter(numbers)
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
# next(it) → StopIteration5. Iterator for a Custom Range Function 🔢
range_iterator.py
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current <= self.end:
value = self.current
self.current += 1
return value
else:
raise StopIteration
for x in MyRange(1, 5):
print(x)6. Reverse Iterator 🔁
reverse_iterator.py
class Reverse:
def __init__(self, items):
self.items = items
self.index = len(items)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index -= 1
return self.items[self.index]
for item in Reverse([10, 20, 30]):
print(item)7. Iterator for Fibonacci Sequence 🌀
fibonacci_iterator.py
class Fibonacci:
def __init__(self, max_limit):
self.a = 0
self.b = 1
self.max = max_limit
def __iter__(self):
return self
def __next__(self):
if self.a > self.max:
raise StopIteration
value = self.a
self.a, self.b = self.b, self.a + self.b
return value
for n in Fibonacci(50):
print(n)8. Iterator Inside a Class (Multiple Iterators) 🧩
multiple_iterators.py
class MyList:
def __init__(self, data):
self.data = data
def __iter__(self):
return iter(self.data) # delegates to built-in iterator
nums = MyList([1, 2, 3, 4])
for n in nums:
print(n)Note
__next__() manually.9. Important Rules for Iterators ⚠️
- __iter__() must return the iterator object.
- __next__() must return the next value or raise StopIteration.
- Iterators maintain internal state.
- Iterators are exhausted once completed (you must create a new one).
10. Real-World Use Cases 🌍
Iterating over database rows
db_iterator.py
# Cursor returned from DB is an iterator
for row in cursor:
print(row)Reading large file line-by-line
file_iterator.py
for line in open("data.txt"):
print(line.strip())Streaming API data
stream_iterator.py
def stream():
while True:
yield fetch_data() # generator → iteratorConclusion 🎉
__iter__ and __next__ give you total control over iteration — the foundation of loops, generators, and lazy evaluation.” ✨You now fully understand __iter__ and __next__ in Python! Want the next topic? Try Decorators, Modules, Classes & Objects (OOP), or Error Handling. Just tell me! 😊