[Python-ideas] Change how Generator Expressions handle StopIteration
Guido van Rossum
guido at python.org
Tue Nov 4 05:49:45 CET 2014
I guess implementing groupby() would be a good interview question. :-)
Can we get back to the issue at hand, which is whether and how we can
change the behavior of StopIteraton to be less error-prone?
On Mon, Nov 3, 2014 at 8:10 PM, Joshua Landau <joshua at landau.ws> wrote:
> On 4 November 2014 00:29, Guido van Rossum <guido at python.org> wrote:
> >
> > Regarding Akira Li's examples of groupby(), unfortunately I find both
> > versions inscrutable -- on a casual inspection I have no idea what goes
> on.
> > I would have to think about how I would write groupby() myself (but I'm
> > pretty sure I wouldn't us functools.partial(). :-)
>
> It's worth noting that the functools.partial doesn't really do
> anything. Just changing
>
> next_value = partial(next, iter(iterable))
>
> to
>
> iterator = iter(iterable)
>
> and "next_value()" to "next(iterator)" gets rid of it.
>
> I would have tackled it by letting the inner iterator set a "finished"
> flag and I would have exhausted the iterable by iterating over it:
>
> def groupby(iterable):
> # Make sure this is one-pass
> iterator = iter(iterable)
> finished = False
>
> # Yields a group
> def yield_group():
> nonlocal finished, group_key
>
> # This was taken off the iterator
> # by the previous group
> yield group_key
>
> for item in iterator:
> if item != group_key:
> # Set up next group
> group_key = item
> return
>
> yield item
>
> # No more items in iterator
> finished = True
>
> # This is always the head of the next
> # or current group
> group_key = next(iterator)
>
> while not finished:
> group = yield_group()
> yield group_key, group
>
> # Make sure the iterator is exhausted
> for _ in group:
> pass
>
> # group_key will now be the head of the next group
>
> This does have a key difference. Whereas with groupby you have the
> confusing property that
>
> from itertools import groupby
>
> grps = groupby("|||---|||")
> a = next(grps)
> b = next(grps)
> c = next(grps)
> list(a[1])
> #>>> ['|', '|', '|']
>
> with mine this does not happen:
>
> grps = groupby("|||---|||")
>
> grps = groupby("|||---|||")
> a = next(grps)
> b = next(grps)
> c = next(grps)
> list(a[1])
> #>>> []
>
> Was this an oversight in the original design or is this actually
> desired? I would guess it's an oversight.
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
--
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20141103/3839e8fe/attachment.html>
More information about the Python-ideas
mailing list