Question

I've got a generator similar to the itertools' pairwise recipe, which yields (s0,s1), (s1,s2), (s2, s3).... I want to create another generator from it that would yield the original sequence s0, s1, s2, s3,....

from itertools import *

def pairwise(iterable):
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

a = [1,2,3,4]

for item in unpair(pairwise(a)):
   print item # should print 1,2,3,4

How to write unpair as a generator, without resorting to lists?

Was it helpful?

Solution

Maybe:

def unpair(iterable):
    p = iter(iterable)
    return chain(next(p, []), (x[1] for x in p))

OTHER TIPS

This should be it:

def unpairwise(iterable):
    for i, (fst, snd) in enumerate(iterable):
        if i == 0:
            yield fst
        yield snd

If you are concerned by the if being evaluated at each loop, you could of course do:

def unpairwise(iterable):
    fst, snd = iterable.next()
    yield fst
    yield snd
    for fst, snd in iterable:
        yield snd

a version of DSM's that is concise, but works for an empty list:

from itertools import islice, chain
def unpair(iterable):
    p = iter(iterable)
    return chain(chain(*islice(p,1)),(x[1] for x in p))

You can try this:

def unpair(iterable):
    it = iter(iterable)
    head = next(it)
    yield head[0]
    yield head[1]
    for fst, snd in it:
        yield snd
>>> from itertools import chain
>>> def unpair(iterable):
...     x, y = zip(*iterable)
...     return chain([x[0]], y)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top