小能豆

What does the "yield" keyword do in Python?

python

What is the use of the yield keyword in Python? What does it do?

For example, I’m trying to understand this code1:

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  

And this is the caller:

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

What happens when the method _get_child_candidates is called? Is a list returned? A single element? Is it called again? When will subsequent calls stop?


阅读 323

收藏
2024-01-02

共1个答案

小能豆

In Python, the yield keyword is used in a function to turn it into a generator. When a function contains the yield statement, it becomes a generator function, and calling this function doesn’t execute it immediately. Instead, it returns an iterator, which can be used to iterate over the values generated by the yield statements.

Let’s break down the code you provided:

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

In this method, yield is used to produce values as part of a generator. It yields _leftchild and _rightchild under certain conditions. When you call _get_child_candidates, it doesn’t execute the method immediately. Instead, it returns a generator object.

Now, when you call this method in a loop as in your example:

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
  • The node._get_child_candidates is called within the loop.
  • It returns a generator object, but the generator function doesn’t start executing immediately.
  • The generator function starts executing when you iterate over it.
  • The extend method is used to add the values yielded by the generator to the candidates list.

The loop continues until there are no more elements in the candidates list. At each iteration, it pops a node from the list, checks conditions, extends the result list, and extends the candidates list with the values yielded by the generator.

The generator function stops when there are no more yield statements or when an explicit return statement is encountered. In your case, the generator stops when there are no more _leftchild or _rightchild nodes to yield based on the specified conditions.

In summary, the yield keyword in _get_child_candidates produces values one at a time, and these values are consumed in the loop until there are no more values to yield. The generator function retains its state between calls, allowing it to resume execution where it left off.

2024-01-02