Loop in a loop?
Paul Hankin
paul.hankin at gmail.com
Thu Jan 17 18:59:44 EST 2008
On Jan 17, 7:02 pm, George Sakkis <george.sak... at gmail.com> wrote:
> On Jan 17, 12:25 pm, Paul Hankin <paul.han... at gmail.com> wrote:
>
>
>
> > On Jan 17, 4:38 pm, Bruno Desthuilliers <bruno.
>
> > 42.desthuilli... at wtf.websiteburo.oops.com> 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
More information about the Python-list
mailing list