Search code examples
pythongeneratorsendyield

Is there a way to update a generator loop condition when that value isn't yielded?


I'm trying to create a counter with a generator, however, I also want to be able to send() and update a generator input (not necessarily yield this input though).

def numberGenerator(n):
 number = 0
 while number < n:
     yield number
     number += 1

I want to be able to do g=numberGenerator(5) -> next(g), 0 -> next(g), 1 -> g.send(10) to update the value n, so that the generator will not stop when it outputs 4, but continues to output until 9. How would I go about this, while still keeping a counter on 'number'?

I'm also quite confused about when I enter g.send(10) because it outputs 2. From what I understand, I think the send value is being sent to the yield number line and then the code below is executed. Shouldn't it return 11 based on the code above?

I've considered trying another yield so that we can actually send a value to n, but I'm not too sure how that would interact with next() and I don't necessarily want to keep the value n.


Solution

  • A generator is always run till the next yield (or till end) - regardless if started by send or next.

    Look at the modified code below. newn is the value you sent to the generator. If you do not specify it, it is None. You can thus distinguish value setting and getting.

    def numberGenerator(n):
        number = 0 
        while number < n:
            newn = yield number
            if newn is None:
                number += 1
            else:
                n = newn