Merge 2 lists at every x position
Question: Say I have two lists one longer than the other, `x = [1,2,3,4,5,6,7,8]` and `y
= [a,b,c]` and I want to merge each element in y to every 3rd index in x so
the resulting list z would look like: `z = [1,2,a,3,4,b,5,6,c,7,8]`

What would be the best way of going about this in python?


Answer: Here is an adapted version of the roundrobin recipe from the [itertools
documentation](http://docs.python.org/2/library/itertools.html#recipes) that
should do what you want:

    
    
    from itertools import cycle, islice
    
    def merge(a, b, pos):
        "merge('ABCDEF', [1,2,3], 3) --> A B 1 C D 2 E F 3"
        iterables = [iter(a)]*(pos-1) + [iter(b)]
        pending = len(iterables)
        nexts = cycle(iter(it).next for it in iterables)
        while pending:
            try:
                for next in nexts:
                    yield next()
            except StopIteration:
                pending -= 1
                nexts = cycle(islice(nexts, pending))
    

Example:

    
    
    >>> list(merge(xrange(1, 9), 'abc', 3))   # note that this works for any iterable!
    [1, 2, 'a', 3, 4, 'b', 5, 6, 'c', 7, 8]
    

Or here is how you could use `roundrobin()` as it is without any
modifications:

    
    
    >>> x = [1,2,3,4,5,6,7,8]
    >>> y = ['a','b','c']
    >>> list(roundrobin(*([iter(x)]*2 + [y])))
    [1, 2, 'a', 3, 4, 'b', 5, 6, 'c', 7, 8]
    

Or an equivalent but slightly more readable version:

    
    
    >>> xiter = iter(x)
    >>> list(roundrobin(xiter, xiter, y))
    [1, 2, 'a', 3, 4, 'b', 5, 6, 'c', 7, 8]
    

Note that both of these methods work with any iterable, not just sequences.

Here is the original `roundrobin()` implementation:

    
    
    from itertools import cycle, islice
    
    def roundrobin(*iterables):
        "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
        # Recipe credited to George Sakkis
        pending = len(iterables)
        nexts = cycle(iter(it).next for it in iterables)
        while pending:
            try:
                for next in nexts:
                    yield next()
            except StopIteration:
                pending -= 1
                nexts = cycle(islice(nexts, pending))
    

