On Sun, Mar 15, 2015 at 11:48 AM, Marko Rauhamaa <ma...@pacujo.net> wrote: > Chris Angelico <ros...@gmail.com>: > >> On Sun, Mar 15, 2015 at 11:15 AM, Marko Rauhamaa <ma...@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 -- https://mail.python.org/mailman/listinfo/python-list