Skip to content

[Python] yield and Generator

Last Updated on 2023-07-11 by Clay

Introduction

yield is a keyword in Python, utilized much like return, the use of yield transforms a function into a Generator.

What is a generator? Think of it as a more straightforward iterator. The primary advantage of a generator is that it allows for lazy evaluation and deferred generation of return values.

This means computations are performed only when generator function is iterated over. This is extremely useful for large-scale calculations or infinite sequences.

At the very least, you won’t have to load all the data into memory all at once.

Let’s explore this concept further with a simple example.


yield and next() sample code

In addition to retrieving values directly using a for loop, we can also use the iter() function in conjunction with next() to obtain values.

It’s worth noting that each time infinite_sequence() is called, a new generator is created. That’s why you see the numbers starting from 1 twice.

# coding: utf-8
from typing import Iterator


def infinite_sequence() -> Iterator[int]:
    num = 0
    while True:
        num += 1
        yield num


def main() -> None:
    # For Loop
    for i in infinite_sequence():
        print("for", i)

        if i >= 5:
            break

    # Next
    sequence_iterator = iter(infinite_sequence())
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))


if __name__ == "__main__":
    main()


Output:

for 1
for 2
for 3
for 4
for 5
next 1
next 2
next 3
next 4
next 5


If you want to see the same sequence of numbers, you should encapsulate it as an iterator at the beginning.

# coding: utf-8
from typing import Iterator


def infinite_sequence() -> Iterator[int]:
    num = 0
    while True:
        num += 1
        yield num


def main() -> None:
    # Init
    sequence_iterator = iter(infinite_sequence())

    # For Loop
    for i in sequence_iterator:
        print("for", i)

        if i >= 5:
            break

    # Next
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))
    print("next", next(sequence_iterator))


if __name__ == "__main__":
    main()


Output:

for 1
for 2
for 3
for 4
for 5
next 6
next 7
next 8
next 9
next 10

In the second version, we observe that using both the for loop and next() operates on the same iterator.


References


Read More

Tags:

Leave a Reply