Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to zip two lists of lists in Python?

Tags:

I have two lists of lists that have equivalent numbers of items. The two lists look like this:

L1 = [[1, 2], [3, 4], [5, 6]]  L2 =[[a, b], [c, d], [e, f]] 

I am looking to create one list that looks like this:

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

I was attempting to use zip() something like this:

for list1, list2 in zip(*L1, *L2):     Lmerge = [list1, list2] 

What is the best way to combine two lists of lists? Thanks in advance.

like image 223
drbunsen Avatar asked Sep 19 '11 17:09

drbunsen


People also ask

Can you zip two lists in Python?

You can also zip two lists in python with the combination of zip() function and for loop. It is the least used method where the interlist aggregation can be done with the chain function, while the intralist aggregation can be done with the zip() function.

How do I zip 3 lists in Python?

Python zip three lists Python zipping of three lists by using the zip() function with as many inputs iterables required. The length of the resulting tuples will always equal the number of iterables you pass as arguments.

Can zip take more than two lists Python?

The Python zip() function makes it easy to also zip more than two lists. This works exactly like you'd expect, meaning you just only need to pass in the lists as different arguments.


2 Answers

>>> map(list.__add__, L1, L2) [[1, 2, 'a', 'b'], [3, 4, 'c', 'd'], [5, 6, 'e', 'f']] 
like image 138
hammar Avatar answered Sep 28 '22 04:09

hammar


>>> L1 = [[1, 2], [3, 4], [5, 6]] >>> L2 =[["a", "b"], ["c", "d"], ["e", "f"]] >>> [x + y for x,y in zip(L1,L2)] [[1, 2, 'a', 'b'], [3, 4, 'c', 'd'], [5, 6, 'e', 'f']] 

Or,

>>> [sum(x,[]) for x in zip(L1,L2)] [[1, 2, 'a', 'b'], [3, 4, 'c', 'd'], [5, 6, 'e', 'f']] 

or,

>>> import itertools >>> [list(itertools.chain(*x)) for x in zip(L1,L2)] [[1, 2, 'a', 'b'], [3, 4, 'c', 'd'], [5, 6, 'e', 'f']] 

We can also do it without zip():

>>> [L1[i] + L2[i] for i in xrange(min(len(L1), len(L2)))]   [[1, 2, 'a', 'b'], [3, 4, 'c', 'd'], [5, 6, 'e', 'f']]  >>> [x + L2[i] for i, x in enumerate(L1)]  # assuming len(L1) == len(l2) [[1, 2, 'a', 'b'], [3, 4, 'c', 'd'], [5, 6, 'e', 'f']]  >>> # same as above, but deals with different lengths >>> Lx, Ly = ((L2,L1), (L1,L2))[len(L1)<=len(L2)] # shortcut for if/else >>> [x + Ly[i] for i, x in enumerate(Lx)] 

Some benchmarks

Here are some benchmarks for the answers provided so far.

It looks like the most popular answer ([x + y for x,y in zip(L1,L2)]) is pretty much on par with @hammar's map solution. On the other hand, the alternative solutions I've given have proven to be rubbish!

However, the fastest solutions (for now) seems to be the ones that uses list comprehension without zip().

[me@home]$ SETUP="L1=[[x,x+1] for x in xrange(10000)];L2=[[x+2,x+3] for x in xrange(10000)]"  [me@home]$ # this raises IndexError if len(L1) > len(L2) [me@home]$ python -m timeit "$SETUP" "[x + L2[i] for i, x in enumerate(L1)]" 100 loops, best of 3: 10.6 msec per loop  [me@home]$ # same as above, but deals with length inconsistencies [me@home]$ python -m timeit "$SETUP" "Lx,Ly=((L2,L1),(L1,L2))[len(L1)<=len(L2)];[x + Ly[i] for i, x in enumerate(Lx)]" 100 loops, best of 3: 10.6 msec per loop  [me@home]$ # almost as fast as above, but easier to read [me@home]$ python -m timeit "$SETUP" "[L1[i] + L2[i] for i in xrange(min(len(L1),len(L2)))]" 100 loops, best of 3: 10.8 msec per loop  [me@home]$ python -m timeit "$SETUP" "L3=[x + y for x,y in zip(L1,L2)]" 100 loops, best of 3: 13.4 msec per loop  [me@home]$ python -m timeit "$SETUP" "L3=map(list.__add__, L1, L2)"  100 loops, best of 3: 13.5 msec per loop  [me@home]$ python -m timeit "$SETUP" "L3=[sum(x,[]) for x in zip(L1,L2)]" 100 loops, best of 3: 18.1 msec per loop  [me@home]$ python -m timeit "$SETUP;import itertools" "L3=[list(itertools.chain(*x)) for x in zip(L1,L2)]" 10 loops, best of 3: 32.9 msec per loop 

@Zac's suggestion is really quick, but then we're comparing apples and oranges here since it does a list extension in-place on L1 instead of creating a third list. So, if L1 is not longer needed, this is a great solution.

[me@home]$ python -m timeit "$SETUP" "for index, x in enumerate(L1): x.extend(L2[index])" 100 loops, best of 3: 9.46 msec per loop 

However, if L1 has to be kept intact, then performance would be sub par once you include the deepcopy.

[me@home]$ python -m timeit "$SETUP;from copy import deepcopy" "L3=deepcopy(L1) > for index, x in enumerate(L1): x.extend(L2[index])" 10 loops, best of 3: 116 msec per loop 
like image 32
Shawn Chin Avatar answered Sep 28 '22 04:09

Shawn Chin