Last Updated: May 22, 2026
A custom iterator class with __iter__ and __next__ works, but the bookkeeping is painful: a state attribute, a manual StopIteration, a fresh class for every new iteration pattern. Generators replace almost all of that with one keyword. A function that contains yield automatically becomes a generator function, and calling it gives you back an iterator with the same iterator protocol, packaged in three lines of code instead of twenty.