Understanding Python's yield Keyword and Generators
This article explains the purpose and behavior of Python's yield keyword, how generators work, their difference from regular functions, and demonstrates practical examples including iterator concepts, itertools utilities, and memory‑efficient looping techniques.
The article introduces the yield keyword in Python, explaining that it turns a function into a generator that produces values lazily, one at a time, without storing the entire sequence in memory.
It first shows a method def node._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 how it is used in a search loop:
result, candidates = list(), [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
To illustrate basic iteration, the article shows a normal list iteration:
mylist = [1, 2, 3] for i in mylist: print(i)
and a list comprehension that creates an iterable:
mylist = [x*x for x in range(3)] for i in mylist: print(i)
It then explains that a generator expression produces an iterator that can be consumed only once:
mygenerator = (x*x for x in range(3)) for i in mygenerator: print(i)
The createGenerator example demonstrates a simple generator function:
def createGenerator(): mylist = range(3) for i in mylist: yield i*i mygenerator = createGenerator() print(mygenerator) # for i in mygenerator: print(i)
The article also mentions the itertools module for advanced iteration, showing how to generate all permutations of four horses:
import itertools horses = [1, 2, 3, 4] races = itertools.permutations(horses) print(list(races))
Further, a detailed walkthrough of a generator with a while True loop illustrates how next() and send() interact with yield :
def foo(): print("starting...") while True: res = yield 4 print("res:", res) g = foo() print(next(g)) # starts execution, yields 4 print("*"*20) print(next(g)) # resumes, res is None, yields 4 again
Using send() to provide a value to the generator:
g = foo() print(next(g)) # yields 4 print(g.send(7)) # sends 7 to res, then yields next 4
Finally, the article compares using a generator versus a list or range for large sequences, showing a memory‑efficient generator that yields numbers up to 10:
def foo(num): print("starting...") while num < 10: num = num + 1 yield num for n in foo(0): print(n)
It notes that in Python 3, range already behaves like the old xrange , providing a lazy sequence without creating a full list.
Test Development Learning Exchange
Test Development Learning Exchange
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.