3

I have two lists with same length:

list_1 = [1,2,3,4,5,6]
list_2 = ['a','b','c','d','e','f']

I need to merge these lists based on n as below:

  • if n = 1: result = [1,'a',2,'b',3,'c',4,'d',5,'e',6,'f']
  • if n = 2: result = [1,2,'a','b',3,4,'c','d',5,6,'e','f']
  • if n = 3: result = [1,2,3,'a','b','c',4,5,6,'d','e','f']
  • if n = 4: result = [1,2,3,4,'a','b','c','d',5,6,'e','f'], and so on

Is there any pythonic way to achieve this? So far I only know to do if n = 1 with list comprehension:

result = [x for sublist in zip(list_1, list_2) for x in sublist]

I don't know how to do it dynamically.

Jeff
  • 97
  • 4

3 Answers3

4

Try itertools(zip_longest and chain.from_iterable) with a list-comprehension, one liner:

import itertools

def merge(l1, l2, n):
    return [j for i in zip(itertools.zip_longest(*[iter(l1)]*n), itertools.zip_longest(*[iter(l2)]*n)) for j in itertools.chain.from_iterable(i) if j]

list_1 = [1, 2, 3, 4, 5, 6]

list_2 = ["a", "b", "c", "d", "e", "f"]

print(merge(list_1, list_2, 2))
# [1, 2, 'a', 'b', 3, 4, 'c', 'd', 5, 6, 'e', 'f']
print(merge(list_1, list_2, 3))
# [1, 2, 3, 'a', 'b', 'c', 4, 5, 6, 'd', 'e', 'f']
print(merge(list_1, list_2, 4))
# [1, 2, 3, 4, 'a', 'b', 'c', 'd', 5, 6, 'e', 'f']

Some possible reference:How does zip(*[iter(s)]*n) work in Python?

jizhihaoSAMA
  • 10,685
  • 9
  • 18
  • 36
  • thank you so much! This solve my problem beautifully. I should start studying itertools! – Jeff Aug 13 '20 at 02:37
0

Alternative answer using generators:

list_1 = [1,2,3,4,5,6]
list_2 = ['a','b','c','d','e','f']

def merge(a, b, n):
    a_index = 0
    b_index = 0
    while(a_index < len(a)):
        for _ in range(n):
            yield a[a_index]
            a_index +=1
        for _ in range(n):
            yield b[b_index]
            b_index += 1

result = [x for x in merge(list_1, list_2, 1)]
assert result == [1, 'a', 2, 'b', 3, 'c', 4, 'd', 5, 'e', 6, 'f']

result = [x for x in merge(list_1, list_2, 2)]
assert result == [1, 2, 'a', 'b', 3, 4, 'c', 'd', 5, 6, 'e', 'f']

result = [x for x in merge(list_1, list_2, 3)]
assert result == [1,2,3,'a','b','c',4,5,6,'d','e','f']

Only works for lists with the same size and probably has some more pitfalls.

Edit: just for fun, here's a version without managing an index.

def merge(a, b, n):
    gen_a = (x for x in a)
    gen_b = (x for x in b)
    try:
        while True:
            for _ in range(n):
                yield next(gen_a)
            for _ in range(n):
                yield next(gen_b)
    except StopIteration:
        pass
Arwalk
  • 188
  • 1
  • 8
-1
def main(order, iArr, sArr):
    arr = []
    for type in order:
        if type == 'i':
            arr.append(iArr[0])
            iArr.remove(iArr[0])
        else:
            arr.append(sArr[0])
            sArr.remove(sArr[0])
    return arr
order1 = ['i', 's', 'i', 's', 'i', 's', 'i', 's', 'i', 's', 'i', 's']
order2 = ['i', 'i', 's', 's', 'i', 'i', 's', 's', 'i', 'i', 's', 's']
order3 = ['i', 'i', 'i', 's', 's', 's', 'i', 'i', 'i', 's', 's', 's']
list_1 = [1,2,3,4,5,6]
list_2 = ['a', 'b', 'c', 'd', 'e', 'f']
print(main(order2, list_1, list_2))
wjandrea
  • 16,334
  • 5
  • 30
  • 53
bays2023
  • 5
  • 4