Need Help With Python Development?

Work with our skilled Python developers to accelerate your project and boost its performance.

Hire Python Developers

Support On Demand!

The yield keyword in Python is used in a function to turn it into a generator. A generator is a type of iterable, like a list or tuple, but it does not store its values in memory all at once. Instead, it generates each value on the fly, one at a time, as needed, using the yield statement.

When a function contains yield, it becomes a generator function, which doesn’t return a value all at once. Instead, it produces a sequence of results lazily, one at a time, each time the yield statement is encountered. This is a powerful tool for handling large data sets or streams of data where you don’t want to store everything in memory at once.

Key Features of yield:

  • Pauses the function’s execution: When the yield keyword is encountered, the function’s execution pauses, and the value is returned to the caller.
  • Resumes where it left off: The function can resume execution from the point it was paused (just after the yield statement) when the next value is requested.
  • Does not require returning all values at once: The function can yield values one by one, conserving memory by not keeping all results in memory at once.

Common Simple Example of yield:

def count_up_to(max):
   count = 1
   while count <= max:
       yield count
       count += 1

counter = count_up_to(5)
for num in counter:
   print(num)

Output:

1
2
3
4
5

Here, count_up_to yields values from 1 to max, one at a time. The function pauses after each yield and resumes when the next value is requested in the loop.

Another Example Breakdown:

Consider the following method with yield:

def _get_child_candidates(self, distance, min_dist, max_dist):
   if self._leftchild and distance - max_dist < self._median:
       yield self._leftchild
   if self._rightchild and distance + max_dist >= self._median:
       yield self._rightchild

What happens here?
Instead of returning a list of child nodes, the function yields each child node one by one based on the conditions.
Each call to _get_child_candidates will return a single child node when the conditions are met, and the function pauses until the next call.

Example of How the Caller Interacts with yield:

result, candidates = [], [self]
while candidates:
   node = candidates.pop()
   distance = node._get_dist(obj)
   if distance <= max_dist and distance >= min_dist:
       result.extend(node._values)
   candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result

Here, candidates.extend() calls _get_child_candidates and collects nodes one at a time through the generator’s yield.

What Happens When _get_child_candidates is Called?

  • When _get_child_candidates is invoked, it does not return a list. Instead, it yields values one at a time based on the conditions.
  • Each time yield is encountered, the function pauses and returns a single child node (either self._leftchild or self._rightchild) to the caller.
  • After that, the function resumes execution when the next value is requested, allowing it to yield more values if further conditions are met.

Related Q&A