4

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, 7]]

L2 =[[a, b], [c, d], [e, f, g]]

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

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

I was attempting to use map() :

map(list.__add__, L1, L2) but the output produces a flat list.

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

Peter Nazarenko
  • 411
  • 1
  • 7
  • 16
user47467
  • 1,045
  • 2
  • 17
  • 34
  • Probable duplication with ["Merging a list of lists"](https://stackoverflow.com/questions/7895449/merging-a-list-of-lists) from October 2011? – Peter Nazarenko Nov 02 '19 at 12:52

2 Answers2

7

You can zip the lists and then zip the resulting tuples again...

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

If you need lists all the way down, combine with `map:

>>> [list(map(list, zip(a,b))) for a,b in zip(L2, L1)]
[[['a', 1], ['b', 2]], [['c', 3], ['d', 4]], [['e', 5], ['f', 6], ['g', 7]]]
tobias_k
  • 81,265
  • 12
  • 120
  • 179
3

You were on the right track with the map.

Here's a shorter alternative to the first version by tobias_k, zip together corresponding elements from both lists:

>>> zipped = map(zip, L2, L1)
>>> list(map(list, zipped)) # evaluate to a list of lists
[[('a', 1), ('b', 2)], [('c', 3), ('d', 4)], [('e', 5), ('f', 6), ('g', 7)]]

As noted in the comments, in Python 2, the brief map(zip, L2, L1) is enough.

map(zip, L2, L1) will work for you in Python 3 too, given that you iterate over it just once and that you don't need sequence access by index. And if you need to iterate many times, you may be interested in itertools.tee.

A shorter alternative to the second version:

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

Lastly, there's also this:

>>> from functools import partial
>>> map(partial(map, list), map(zip, L2, L1))
[[['a', 1], ['b', 2]], [['c', 3], ['d', 4]], [['e', 5], ['f', 6], ['g', 7]]]
arekolek
  • 9,128
  • 3
  • 58
  • 79
  • 1
    Nice. In fact, in Python 2, the first one is equivalent to just `map(zip, L2, L1)` -- but you'd probably need at least as many characters to explain what this does. ;-) – tobias_k Feb 19 '16 at 11:51
  • @tobias_k: Thanks for pointing this out. I assumed we were talking Python 3 and that OP really needs a list. But for other people, the shortest version may be suitable even if they ditched Python 2. Arguably, it may actually be the most readable, at least for people familiar with `map` and `zip`. – arekolek Feb 20 '16 at 09:24