Andrew Dalke wrote: > Peter Otten wrote: >> Combining your "clever" and your "elegant" approach to something fast >> (though I'm not entirely confident it's correct): >> >> def fillzip(*seqs): >> def done_iter(done=[len(seqs)]): >> done[0] -= 1 >> if not done[0]: >> return >> while 1: >> yield None >> seqs = [chain(seq, done_iter()) for seq in seqs] >> return izip(*seqs) > > Ohh, that's pretty neat passing in 'done' via a mutable default argument. > > It took me a bit to even realize why it does work. :)
Though I would never have come up with it, were it not for the juxtaposition of your two variants (I initially disliked the first and tried to improve on the second), it is an unobvious merger :) It's a bit fragile, too, as > Could make it one line shorter with > from itertools import chain, izip, repeat > def fillzip(*seqs): > def done_iter(done=[len(seqs)]): > done[0] -= 1 > if not done[0]: > return [] > return repeat(None) > seqs = [chain(seq, done_iter()) for seq in seqs] > return izip(*seqs) that won't work because done_iter() is now no longer a generator. In effect you just say seqs = [chain(seq, repeat(None)) for seq in seqs[:-1]] + [chain(seq[-1], [])] I tried class Done(Exception): pass pad = repeat(None) def fillzip(*seqs): def check(active=[len(seqs)]): active[0] -= 1 if not active[0]: raise Done # just to turn check() into a generator if 0: yield None seqs = [chain(seq, check(), pad) for seq in seqs] try for item in izip(*seqs): yield item except Done: pass to be able to use the faster repeat() instead of the while loop, and then stared at it for a while -- in vain -- to eliminate the for item... loop. If there were a lazy ichain(iter_of_iters) you could tweak check() to decide whether a repeat(None) should follow it, but I'd rather not ask Raymond for that particular addition to the itertools. > Now add the performance tweak.... > > def done_iter(done=[len(seqs)], forever=forever, table=table) > > Okay, I'm over it. :) Me too. I think. For now... Peter -- http://mail.python.org/mailman/listinfo/python-list