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@landau.ws> wrote:
On 4 November 2014 00:29, Guido van Rossum <guido@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@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/



--
--Guido van Rossum (python.org/~guido)