add tag
Anonymous 2391
I am trying to learn how generators work and part of that is the `send()` command that allows me to change the operation of the generator by sending back information to the generator.

I have a very simple example in which I am sending back the yielded value and add it to an internal `status`. 
The generator can be started specifying the number of values it is supposed to yield.

The incredibly strange thing is: When I start the generator with an even number it works, however if I ask to yield an odd number of values I get an `StopIteration` error.


To debug, I added a simple `print()` to keep track of how many iterations it goes through and it seems like it does two iterations per `yield` statement, which makes no sense to me.

The Code:
```
def jump_ahead(length):
    """
    generator that jumps ahead
    """
    status = 1
    iteration = 0
    while iteration < length:
        iteration += 1
        print("iteration: ", iteration)
        result = (yield status)
        if result is not None:
            status += result


if __name__ == "__main__":
    # simple generator that expects a value back
    # this works
    jumpy = jump_ahead(4)
    for i in jumpy:
        jumpy.send(i)
        print(i)
    # this does not
    jumpy_fail = jump_ahead(5)
    for i in jumpy_fail:
        jumpy_fail.send(i)
        print(i)
```

The output looks something like this
``` 
iteration:  1
iteration:  2
1
iteration:  3
iteration:  4
2
iteration:  1
iteration:  2
1
iteration:  3
iteration:  4
2
iteration:  5
  (...) StopIteration
```
Top Answer
Pax
As it is said in the docs,

> `generator.send()` Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.
> 
> https://docs.python.org/3/reference/expressions.html#generator.send

Your code is not doing "two iterations per yield". It is iterating twice because you are yielding twice:

- In the `for...in...` statement
- By calling `.send()`

And `StopIteration` is actually raised on both. With `jump_ahead(4)` it is caught and handled by the `for ... in ...` statement. That's how `for ... in` statements know when to [stop iterating](https://docs.python.org/3/library/exceptions.html#StopIteration).

However, with odd numbers as you have observed, StopIteration was raised when calling `.send()`.

This room is for discussion about this question.

Once logged in you can direct comments to any contributor here.

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.