Search notes:

Python: generators

A generator creates iterators.
That is, a generator creates an object with __iter__ and __next__ methods and which raise the StopIteration exception automatically behind the scenes.

Creating a generator objects

yield

In order to define a generator function, the yield statement (or the equivalent(?) yield expression) is used.
def gen():
    yield 42
    yield 99
    yield -1

g = gen()

print(g.__class__) # <class 'generator'>

g.__next__()  # 42
g.__next__()  # 99
g.__next__()  # -1
g.__next__()  #    -> StopIteration is raised

a = [1,2,3,4,5]
g = (b+10 for b in a)
g.__class__           # -> <class 'generator'>

Generator methods .send(), .throw(), .close()

PEP 342 added the methods .send(), .throw() and .close() to generators.

send()

send() takes exactly one argument.
Calling .send(None) is equivalent to calling next().
send(), like next(), returns the next yielded value or raises StopIteration.
def gen():
   val_to_user = 42
   while( val_from_user := (yield val_to_user)) != None:
       val_to_user = val_from_user + 3

g = gen()
g.send(None)   #  42
g.send(17)     #  20
g.send(3)      #  6
g.send(None)   #  Raises StopIteration

Generator expression

A generator expression is basically an expression followed by a for and optional if clause:
>>> gen_expr = ( math.sqrt(i) for i in [3,-2,5,6] if i >= 0 )
>>> type(gen_expr)

<class 'generator'>

Problems

Because the presence or absence of yield or yield from in a function's body determines if the function is a generator («coroutine»), refactoring (i. e. removing/adding yield or yield from to/from a function) can lead to unobvious errors.

See also

iterators

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/developm...', 1788361304, '216.73.217.21', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/development/languages/Python/generators/index(112): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78