How to merge N multi-lists into one big multi-list?

Viewed 122

I have n multi-lists. I want to merge them into one big multi-list. Example:

   listA =  [[1,2],[3,4],[6,7]]
   listB =  [[10,20],[30,40],[60,70]]

output:

  listAB = [[1,2,10,20],[3,4,30,40],[6,7,60,70]]

This is the code I wrote which computes the above:

listAB,tmp = [],[]
for i in range(len(listA)):
    for j in range(len(listA[i])):
        tmp.append(listA[i][j])
        tmp.append(listB[i][j])
    listAB.append(tmp)
    tmp = []

This code only works when you have two list, and the sub-list have the same length. I want to merge multiple multi-lists which have different lengths of sub-lists. Is there some function in itertools which can do these?

For example:

   listA =  [[1,2,3],[3,4,5],[6,7,8]]
   listB =  [[10,20],[30,40],[60,70]]
   listC =  [[4,4],[5,5],[6]]

   listABC = [[1,2,3,10,20,4,4],
              [3,4,5,30,40,5,5],
              [6,7,8,60,70,6]]
3 Answers

zip the lists together and use itertools.chain to concatenate the output tuples:

from itertools import chain

listABC = [list(chain.from_iterable(i)) for i in zip(listA, listB, listC)]

Output:

[[1, 2, 3, 10, 20, 4, 4], [3, 4, 5, 30, 40, 5, 5], [6, 7, 8, 60, 70, 6]]

Although directly appending the lists is simpler for 3 inputs, with this approach you can also pass an arbitrary number of lists using the star operator:

# this can also be a tuple or any iterable
list_of_lists = [listA, listB, listC, listD ... ]

[list(chain.from_iterable(i)) for i in zip(*list_of_lists)]

UPDATE: an alternative solution (not recommended) using functools instead of itertools (as per the discussion with ReblochonMasque):

from functools import reduce

[reduce(lambda x,y: x+y, i) for i in zip(listA, listB, listC)]

For two sequences, you can add them in a list comprehension:

[a+b for a, b in zip(A, B)]

For more than two, @meowgoesthedog answer is appropriate.
If for some reasons, you cannot use itertools, you could maybe do like this:

def merge(seq1, seq2):
    return (a+b for a, b in zip(seq1, seq2))

def merge_all(s):
    res = merge(s[0], s[1])
    for sn in s[2:]:
        res = merge(res, sn)
    return list(res)

A =  [[1,2],[3,4],[6,7]]
B =  [[10,20],[30,40],[60,70]]
C =  [[4,4],[5,5],[6]]

seq = [A, B, C]
merge_all(seq)

I believe you can merge multiple multi-lists which have different lengths of sub-lists just by some simple code w/o using any itertools:

listCom = []
for n in range(len(listA)):
    listCom.append(listA[n] + listB[n] + listC[n])
listCom

The output is:

[[1, 2, 3, 10, 20, 4, 4], [3, 4, 5, 30, 40, 5, 5], [6, 7, 8, 60, 70, 6]]
Related