On 12/7/2014 7:12 PM, Roy Smith wrote:
Chris Angelico wrote:
I'm actually glad PEP 479 will break this kind of code. Gives a good
excuse for rewriting it to be more readable.

Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote:
What kind of code is that? Short, simple, Pythonic and elegant? :-)

Here's the code again, with indentation fixed:


def myzip(*args):
     iters = map(iter, args)
     while iters:
         res = [next(i) for i in iters]
         yield tuple(res)

Ugh.  When I see "while foo", my brain says, "OK, you're about to see a
loop which is controlled by the value of foo being changed inside the
loop".  That's not at all what's happening here, so my brain runs into a
wall.

I agree.  Too tricky.  The code should have been

def myzip(*args):
    if args:
        iters = map(iter, args)
        while True:
            res = [next(i) for i in iters]
            yield tuple(res)

However, this 'beautiful' code has a trap. If one gets rid of the seemingly unneeded temporary list res by telescoping the last two lines into a bit too much into

            yield tuple(next(i) for i in iters)

we now have an infinite generator, because tuple() swallows the StopIteration raised as a side-effect of next calls.

def myzip(*args):
    if args:
        iters = map(iter, args)
        while True:
            try:
                result = [next(i) for i in iters]
            except StopIteration
                return
            yield tuple(res)

makes the side-effect dependence of stopping clearer.  Putting
                 yield tuple([next(i) for i in iters])
in the try would also work.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to