- Introduction to Iterables and Iterators
- Creating Iterators with iter() and next()
- Building Custom Iterators
- Building Generators with yield
- Generator Expressions
- Use Cases for Generators
- Summary
- Tasks
In Python, an iterable is an object that can return an iterator. An iterator is an object that represents a stream of data. Iterators allow you to traverse through all the elements of a collection, one element at a time.
Lists, tuples, and strings are examples of iterables.
l = [1, 2, 3]
for i in l:
print(i)
Output:
1
2
3
Explanation: The list l
is an iterable, and we can use a for
loop to iterate over its elements.
You can create an iterator from an iterable using the iter()
function. The next()
function is used to get the next item from the iterator.
l = [1, 2, 3]
iter_l = iter(l)
print(next(iter_l))
print(next(iter_l))
print(next(iter_l))
Output:
1
2
3
Explanation: We create an iterator iter_l
from the list l
using the iter()
function. We then use the next()
function to get the next item from the iterator.
When there are no more items to return, the next()
function raises a StopIteration
exception.
l = [1, 2, 3]
iter_l = iter(l)
while True:
try:
print(next(iter_l))
except StopIteration:
break
Output:
1
2
3
Explanation: We use a while
loop and a try-except
block to handle the StopIteration
exception and stop the iteration.
You can create custom iterators by defining a class with __iter__
and __next__
methods.
class CustomRange:
def __init__(self, start, end, step=1):
self.value = start
self.end = end
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.value >= self.end:
raise StopIteration
current = self.value
self.value += self.step
return current
numbers = CustomRange(1, 5, 1)
for num in numbers:
print(num)
Output:
1
2
3
4
Explanation: The CustomRange
class defines a custom iterator that generates numbers from start
to end
with a given step
. The __iter__
method returns the iterator object itself, and the __next__
method returns the next value in the sequence or raises a StopIteration
exception when the end is reached.
Generators are a simple way to create iterators. A generator is a function that uses the yield
keyword to return values one at a time.
def custom_range(start, end, step=1):
current = start
while current < end:
yield current
current += step
numbers = custom_range(1, 5)
for num in numbers:
print(num)
Output:
1
2
3
4
Explanation: The custom_range
function is a generator that yields values from start
to end
with a given step
. We use a for
loop to iterate over the generated values.
Generator expressions provide a concise way to create generators. They are similar to list comprehensions but use parentheses instead of square brackets.
gen_exp = (x * x for x in range(5))
for num in gen_exp:
print(num)
Output:
0
1
4
9
16
Explanation: The generator expression (x * x for x in range(5))
creates a generator that yields the squares of numbers from 0 to 4. We use a for
loop to iterate over the generated values.
Generators are useful for working with large datasets, as they generate values on the fly and do not store them in memory. This makes them memory-efficient and suitable for tasks like reading large files or generating infinite sequences.
def read_large_file(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line
for line in read_large_file('large_file.txt'):
print(line.strip())
Explanation: The read_large_file
function is a generator that reads a large file line by line. We use a for
loop to iterate over the lines and print them.
def infinite_sequence():
num = 0
while True:
yield num
num += 1
gen = infinite_sequence()
for i in range(10):
print(next(gen))
Output:
0
1
2
3
4
5
6
7
8
9
Explanation: The infinite_sequence
function is a generator that yields an infinite sequence of numbers starting from 0. We use a for
loop to get the first 10 numbers from the generator.
In this chapter, we covered iterables, iterators, and generators in Python. We learned how to create iterators using the iter()
and next()
functions, build custom iterators, build generators using the yield
keyword, and use generator expressions for concise generator creation. We also explored use cases for generators, such as reading large files and generating infinite sequences.
- Write a generator function that yields the first
n
Fibonacci numbers. - Create a generator expression that generates the cubes of numbers from 1 to 10.
- Write a program that uses a generator to read a large file line by line and count the number of lines.
- Create a custom iterator class that iterates over a range of numbers with a given step.
- Write a generator function that generates an infinite sequence of even numbers.