generator/coroutine terminology

Chris Angelico rosuav at gmail.com
Sat Mar 14 22:02:33 EDT 2015


On Sun, Mar 15, 2015 at 11:48 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Chris Angelico <rosuav at gmail.com>:
>
>> On Sun, Mar 15, 2015 at 11:15 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>>> What features do generator iterators provide on top of generic
>>> iterators?
>>
>> You can send values into them, throw exceptions into them, and close
>> them (which is a special case of the latter).
>
> Hm. I wonder why the distinction was made. IOW, why is
>
>    iter([1, 2, 3])
>
> not equivalent with
>
>    (x for x in [1, 2, 3])
>
> I can close the latter but not the former.

You don't need to close the former.

> After all,
>
>    yield from [1, 2, 3]
>
> works all right.

That's using it as an iterable, which is not quite the same as an
iterator. (Iterators are themselves iterable; iter(x) is x, for any
iterator.) What you're doing there is roughly equivalent to:

for x in [1, 2, 3]:
    yield x

but with a bunch of other simplifications and guarantees for edge
cases and things. So it's going to call iter() on what you give it.

If you treat things as iterators, you can use all sorts of things. You
don't need to distinguish the different types. The distinction is
important if you want to do more than just iterate over something.

>>> def gather():
    lst = []
    try:
      while True:
        lst.append((yield len(lst)))
    except StopIteration:
      yield lst

>>> n = gather()
>>> next(n)
0
>>> n.send("Hello")
1
>>> n.send("World")
2
>>> n.throw(StopIteration)
['Hello', 'World']

You can't do that with a simple iterator. (Not that I'm saying this is
good design...)

ChrisA



More information about the Python-list mailing list