On Jan 17, 7:02 pm, George Sakkis <[EMAIL PROTECTED]> wrote: > On Jan 17, 12:25 pm, Paul Hankin <[EMAIL PROTECTED]> wrote: > > > > > On Jan 17, 4:38 pm, Bruno Desthuilliers <bruno. > > > [EMAIL PROTECTED]> wrote: > > > Now there are very certainly smart solutions using itertools, but the > > > one I cooked is way too ugly so I'll leave this to itertools masters !-) > > > Here's my effort: > > > from itertools import izip, islice, chain, repeat > > > def padzip(*xs, **kw): > > pad = kw.get('padding', None) > > maxlen = max(len(x) for x in xs) > > return islice(izip(*[chain(x, repeat(pad)) for x in xs]), maxlen) > > > -- > > Paul Hankin > > And if the iterables don't necessarily support len(), here's a more > general solution: > > from itertools import repeat > > def izippad(*iterables, **kw): > pad = kw.get('padding', None) > next_pad = repeat(pad).next > getnext = [iter(iterable).next for iterable in iterables] > pending = size = len(iterables) > while True: > slice = [None] * size > for i in xrange(size): > try: slice[i] = getnext[i]() > except StopIteration: > pending -= 1 > if not pending: return > getnext[i] = next_pad > slice[i] = pad > yield slice
Instead of counting the exceptions, we can limit the padding iterables by using an iterator that returns len(iterables) - 1 padding generators, use a sort of lazy chain, and then just izip. from itertools import izip, repeat def chain_next(xs, yg): for x in xs: yield x for y in yg.next(): yield y def izippad(*xs, **kw): padder = repeat(kw.get('padding', None)) padder_gen = repeat(padder, len(xs) - 1) return izip(*[chain_next(x, padder_gen) for x in xs]) -- Paul Hankin -- http://mail.python.org/mailman/listinfo/python-list