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