Alex Balgavy

Just some stuff about me.

Here's my dotfiles repository.

Check out my blog.

My keys: PGP, SSH

My crypto wallets (BTC, XMR)


What links here:

Generators in Python

Here’s how you can use a generator to get three even numbers:

def even_gen(start=0):
    iterations = 0
    if start % 2 != 0:
        start += 1

    while iterations < 3:
        # `yield` transfer control to the calling function
        yield start
        start += 2
        iterations += 1

g = even_gen()
while True:
    try:
        print(f"got {next(g)}")
    # `StopIteration` is automatically raised when the generator is finished
    except StopIteration:
        print("Done!")
        break

You can create a generator expression with parentheses:

numbers = [1,2,3,4,]
gen = (n for n in numbers)
print(next(gen))

You can pass values into a generator:

def doubler():
    out = None
    while True:
        ipt = yield out
        if ipt is None:
            break
        out = ipt * 2

dbl = doubler()
next(dbl)
print(f'Double of 2 is {dbl.send(2)}')
print(f'Double of 4 is {dbl.send(4)}')
dbl.close()

You can choose which generator to use with yield from:

def odds():
    yield "Yielding odds"
    yield from [1,3,5,7]

def evens():
    yield "Yielding evens"
    yield from [0,2,4,6]

def dispatcher():
    choice = yield "Send even for evens, odd for odds."
    if choice % 2 == 0:
        yield from evens()
    else:
        yield from odds()

Here’s what that would look like in practice:

>>> d = dispatcher()
>>> next(d)
'Send even for evens, odd for odds.'
>>> d.send(2)
'Yielding evens'
>>> next(d)
0
>>> next(d)
2
>>> next(d)
4
>>> next(d)
6
>>> next(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration