Both generators and iterators are used to iterate over data in Python, but they differ in how they are implemented and used.


FeatureIteratorGenerator
DefinitionAn object that implements the __iter__() and __next__() methods.A special type of iterator created using a function with yield or generator expression.
CreationCreated using classes or the iter() function.Created automatically using a yield statement inside a function.
Memory UsageCan be memory-heavy if it stores large data.Memory-efficient — generates items on the fly.
Return TypeReturns data using the return statement.Returns data using the yield keyword.
Syntax SimplicityMore complex (requires class implementation).Easier and cleaner to implement.
ReusabilityOnce exhausted, needs to be recreated manually.Once exhausted, also needs to be recreated.

🧩 Example 1: Iterator

# Creating an iterator using a class
class Counter:
    def __init__(self, low, high):
        self.current = low
        self.high = high

    def __iter__(self):
        return self

    def __next__(self):
        if self.current > self.high:
            raise StopIteration
        else:
            num = self.current
            self.current += 1
            return num

counter = Counter(1, 5)
for num in counter:
    print(num)

Output:

1
2
3
4
5

🧩 Example 2: Generator

# Creating a generator using yield
def counter(low, high):
    while low <= high:
        yield low
        low += 1

for num in counter(1, 5):
    print(num)

Output:

1
2
3
4
5

🧩 Example 3: Generator Expression (Compact Form)

squares = (x*x for x in range(5))
print(next(squares))
print(next(squares))

Output:

0
1

In Summary:

  • Iterators are objects following the iterator protocol (__iter__() and __next__()).
  • Generators are a simpler way to create iterators using yield.
  • Generators are more memory-efficient and easier to implement than custom iterators.

Scroll to Top