Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge 2 lists at every x position

Tags:

python

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?

like image 512
KingFu Avatar asked Jun 21 '13 18:06

KingFu


1 Answers

Here is an adapted version of the roundrobin recipe from the itertools documentation 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))
like image 171
Andrew Clark Avatar answered Oct 08 '22 21:10

Andrew Clark