What it is

The yield keyword is what constitutes a generator function, by changing the way a traditional function behaves when it’s called.

Here’s the key difference in behavior: a regular function exits when it hits a return statement.

def regular_function():
    return 1
 
result = regular_function()  # Executes immediately, returns 1
print(result)  # 1

A generator function, on the other hand, doesn’t actually run the code when it’s called. Instead, it returns a generator object that can be iterated over.

def generator_function():
    yield 1
    print("You just called the generator again!")
    yield 2
 
# Calling the generator function (doesn't execute its code)
generator_object = generator_function()
 
print(generator_object) # <generator object generator_function at 0x...>
 
result = next(generator_object)  # Executes the generator function up to the first yield
print(result)  # 1
 
result = next(generator_object)  # Resumes execution after the first yield
print(result)  # 2

The code inside the generator function only runs when you iterate over it or call next() on it, and it pauses at each yield statement so it can be resumed later.

How it works

In summary, this is how yield works:

  • Unlike return, which exits a function completely, yield pauses the function and saves its state
  • When the generator is called again (in the next iteration), it resumes right where it left off, with all variables intact
  • Each time yield is encountered, it produces a value to the caller, then waits
  • The function keeps its “memory” between calls - variables maintain their values

TIP

Think of it like a bookmark in a book: return closes the book and forgets your page, while yield bookmarks your spot so you can continue reading later.