Automatically advancing a bi-directional generator to the point of accepting a non-None value?

Go Luhng goluhng at gmail.com
Sat Nov 21 14:30:55 EST 2020


Suppose we write a very simple bi-directional generator in Python:

    def share_of_total():
        s = 0
        new_num = 0
        while True:
            new_num = yield new_num / (s or 1)
            s += new_num

    share_calculator = share_of_total()
    next(share_calculator)  # Without this we get the TypeError

    for num in [1, 2, 3]:
        print(share_calculator.send(num))

This generator just accepts a number and yields a float representing
its share of the sum of all previously provided numbers.

We would ideally like to just use it immediately as follows:

    share_calculator = share_of_total()
    print(share_calculator.send(num))

However, this causes `TypeError: can't send non-None value to a
just-started generator`. All users of the `share_of_total()` must
remember to execute `next(share_calculator)` before the generator is
usable as intended.

Is there an elegant way to make `share_calculator` immediately usable
- i.e. to be able to immediately call `share_calculator.send(num)`
after creating `share_calculator`?

I know it can be done with a fairly trivial wrapper, but I was hoping
for a more elegant solution that doesn't require boilerplate.


More information about the Python-list mailing list