Chapter 8 Exercises
Comprehensive exercises covering iterators and generators in Python, sorted from easiest to hardest.
Exercises
Exercise 1: Basic Iterator Class
Create a class called CountDown that implements the iterator protocol. It should start at a given number and count down to 0 (inclusive). Read the start value and print all numbers.
Basic Iterator Class
class CountDown: def __init__(self, start): self.current = start
def __iter__(self): return self
def __next__(self): if self.current < 0: raise StopIteration value = self.current self.current -= 1 return value
start = int(input())counter = CountDown(start)for num in counter: print(num)Exercise 2: Basic Generator Function
Create a generator function called squares that takes a limit n and yields squares of numbers from 0 to n-1. Read n and print all squares.
Basic Generator Function
def squares(limit): for i in range(limit): yield i ** 2
n = int(input())for square in squares(n): print(square)Exercise 3: Using iter() and next()
Create a list [10, 20, 30, 40, 50]. Use iter() to get an iterator, then use next() to get the first three values. Print each value on a separate line.
Using iter() and next()
my_list = [10, 20, 30, 40, 50]iterator = iter(my_list)
print(next(iterator))print(next(iterator))print(next(iterator))Exercise 4: Generator Expression
Create a generator expression that generates cubes (x³) of numbers from 0 to n-1. Read n, convert to list, and print.
Generator Expression
n = int(input())cubes = (x ** 3 for x in range(n))print(list(cubes))Exercise 5: Using enumerate()
Read a number n, then read n strings. Use enumerate() to iterate and print each string with its 1-based index in format “Index: value”.
Using enumerate()
n = int(input())items = []for i in range(n): items.append(input())
for index, value in enumerate(items, start=1): print(f"{index}: {value}")Exercise 6: Using zip()
Read two numbers n and m, then read n names and m scores. Use zip() to combine them and print each name with its score in format “Name: Score”. If lists differ in length, process only the shorter length.
Using zip()
n = int(input())m = int(input())
names = []for i in range(n): names.append(input())
scores = []for i in range(m): scores.append(int(input()))
for name, score in zip(names, scores): print(f"{name}: {score}")Exercise 7: Even Numbers Generator
Create a generator function even_numbers that takes start and end, and yields even numbers in that range (inclusive start, exclusive end). Read start and end, print all even numbers.
Even Numbers Generator
def even_numbers(start, end): for num in range(start, end): if num % 2 == 0: yield num
start = int(input())end = int(input())
for num in even_numbers(start, end): print(num)Exercise 8: Custom Range Iterator
Create a class MyRange implementing the iterator protocol. It takes start, stop, and optional step (default 1), and yields values like range(). Read start, stop, step, then print all values.
Custom Range Iterator
class MyRange: def __init__(self, start, stop, step=1): self.start = start self.stop = stop self.step = step self.current = start
def __iter__(self): return self
def __next__(self): if (self.step > 0 and self.current >= self.stop) or \ (self.step < 0 and self.current <= self.stop): raise StopIteration
value = self.current self.current += self.step return value
start = int(input())stop = int(input())step = int(input())
my_range = MyRange(start, stop, step)for num in my_range: print(num)Exercise 9: Fibonacci Generator
Create a generator function fibonacci that takes a limit and yields the first limit Fibonacci numbers. Read limit and print all numbers.
Fibonacci Generator
def fibonacci(limit): prev, curr = 0, 1 count = 0 while count < limit: yield prev prev, curr = curr, prev + curr count += 1
limit = int(input())for num in fibonacci(limit): print(num)Exercise 10: Generator with Condition
Create a generator expression that generates numbers from 0 to n-1 divisible by 3 or 5. Read n, convert to list, and print.
Generator with Condition
n = int(input())divisible = (x for x in range(n) if x % 3 == 0 or x % 5 == 0)print(list(divisible))Exercise 11: Using reversed()
Read a number n, then read n integers into a list. Use reversed() to iterate in reverse order and print each number.
Using reversed()
n = int(input())numbers = []for i in range(n): numbers.append(int(input()))
for num in reversed(numbers): print(num)Exercise 12: Prime Numbers Generator
Create a generator function primes that takes a limit and yields all prime numbers up to (but not including) limit. Read limit and print all primes.
Prime Numbers Generator
def is_prime(n): if n < 2: return False for i in range(2, int(n ** 0.5) + 1): if n % i == 0: return False return True
def primes(limit): for num in range(2, limit): if is_prime(num): yield num
limit = int(input())for prime in primes(limit): print(prime)Exercise 13: Iterator with State
Create a class Cycle that implements the iterator protocol. It takes a list and cycles through it indefinitely (or up to a limit). Read n (number of items), then the items, then limit. Print limit values from the cycle.
Iterator with State
class Cycle: def __init__(self, items, limit): self.items = items self.limit = limit self.index = 0 self.count = 0
def __iter__(self): return self
def __next__(self): if self.count >= self.limit: raise StopIteration
value = self.items[self.index] self.index = (self.index + 1) % len(self.items) self.count += 1 return value
n = int(input())items = []for i in range(n): items.append(input())
limit = int(input())cycle = Cycle(items, limit)for item in cycle: print(item)Exercise 14: Generator Pipeline
Create two generator functions: numbers(n) that yields 0 to n-1, and squares(nums) that takes an iterator and yields squares. Chain them: squares(numbers(n)). Read n and print all squared values.
Generator Pipeline
def numbers(n): for i in range(n): yield i
def squares(nums): for num in nums: yield num ** 2
n = int(input())pipeline = squares(numbers(n))for value in pipeline: print(value)Exercise 15: Multiple Generator Expressions
Create a generator expression that generates pairs (x, y) where x and y are from 0 to n-1, but only include pairs where x < y. Read n, convert to list, and print.
Multiple Generator Expressions
n = int(input())pairs = ((x, y) for x in range(n) for y in range(n) if x < y)print(list(pairs))Exercise 16: Separating Iterable and Iterator
Create a class Squares (iterable) that has __iter__() returning a SquareIterator. SquareIterator yields squares from 0 to n-1. Read n, create Squares, iterate twice to show independent iterations.
Separating Iterable and Iterator
class SquareIterator: def __init__(self, limit): self.current = 0 self.limit = limit
def __iter__(self): return self
def __next__(self): if self.current >= self.limit: raise StopIteration value = self.current ** 2 self.current += 1 return value
class Squares: def __init__(self, limit): self.limit = limit
def __iter__(self): return SquareIterator(self.limit)
n = int(input())squares = Squares(n)
for num in squares: print(num)
for num in squares: print(num)Exercise 17: Infinite Generator
Create an infinite generator function natural_numbers() that yields natural numbers starting from 1. Use it to print the first n natural numbers. Read n.
Infinite Generator
def natural_numbers(): num = 1 while True: yield num num += 1
n = int(input())gen = natural_numbers()for i in range(n): print(next(gen))Exercise 18: Complex Generator Function
Create a generator function multiples_of(m, limit) that yields multiples of m up to limit. Read m and limit, print all multiples.
Complex Generator Function
def multiples_of(m, limit): num = m while num < limit: yield num num += m
m = int(input())limit = int(input())
for multiple in multiples_of(m, limit): print(multiple)Exercise 19: Generator with Multiple Yields
Create a generator function alternating_pattern(n) that yields “even”, “odd”, “even”, “odd” for n iterations. Read n and print all values.
Generator with Multiple Yields
def alternating_pattern(n): for i in range(n): if i % 2 == 0: yield "even" else: yield "odd"
n = int(input())for value in alternating_pattern(n): print(value)Exercise 20: Complete Iterator System
Create a class BoundedRange implementing the iterator protocol. It takes start, stop, step, and max_iterations. It yields values like range but stops after max_iterations. Read all parameters and print values.
Complete Iterator System
class BoundedRange: def __init__(self, start, stop, step, max_iterations): self.start = start self.stop = stop self.step = step self.current = start self.max_iterations = max_iterations self.count = 0
def __iter__(self): return self
def __next__(self): if self.count >= self.max_iterations: raise StopIteration
if (self.step > 0 and self.current >= self.stop) or \ (self.step < 0 and self.current <= self.stop): raise StopIteration
value = self.current self.current += self.step self.count += 1 return value
start = int(input())stop = int(input())step = int(input())max_iter = int(input())
bounded = BoundedRange(start, stop, step, max_iter)for num in bounded: print(num)