3

How do I concatenate two lists inside the nested list Python?

I have this list

lists_of_lists =[[[1],[2]],[[3],[5]],[[6],[6]]]

And my expected output is

lists_of_lists =[[1,2],[3,5],[6,6]]

I tried this way

new = []
lists_of_lists =[[[1],[2]],[[3],[5]],[[6],[6]]]
for i in range(len(lists_of_lists)):
    for list in  lists_of_lists[i]:
        for element in list:
            new.append(element)
print(new)

But I got

[1, 2, 3, 5, 6, 6]

Thank you for any suggestions

Ada
  • 55
  • 1
  • 9

7 Answers7

4

You can use operator.concat() to group 2 separate lists into one and itertools.starmap() to iterate over main list and unpack inner lists:

from operator import concat
from itertools import starmap

result = list(starmap(concat, lists_of_lists))

You can do it also without imports using built-in map() function and lambda expression (but why?):

result = list(map(lambda x: x[0] + x[1], lists_of_lists))

You can also use chain.from_iterable():

from itertools import chain

result = list(map(list, map(chain.from_iterable, lists_of_lists)))

But if you want want to patch code you've written to work as you expected:

lists_of_lists =[[[1],[2]],[[3],[5]],[[6],[6]]]
new = []
for sub_list in lists_of_lists:
    new_item = []
    for item in sub_list:
        for element in item:
           new_item.append(element)
    new.append(new_item)
Olvin Roght
  • 7,677
  • 2
  • 16
  • 35
3
[[i for inner in sub_lists for i in inner] for sub_lists in lists_of_lists]

# [[1, 2], [3, 5], [6, 6]]
r.ook
  • 13,466
  • 2
  • 22
  • 39
3

You can try this.

[sum(i,[]) for i in lists_of_lists]

[[1, 2], [3, 5], [6, 6]]

Some timeit analysis on the suggested solutions (python 3.7 and windows 10)

Benchmarking list =[[[1],[2]],[[3],[5]],[[6],[6]]]

In [48]: timeit [sum(i,[]) for i in lists_of_lists]
914 ns ± 103 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [49]: timeit [[i for inner in sub_lists for i in inner] for sub_lists in lists_of_lists]
1.25 µs ± 136 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [64]: timeit list(starmap(concat, lists_of_lists))
639 ns ± 30 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [70]: timeit list(map(list, map(chain.from_iterable, lists_of_lists)))
1.55 µs ± 57 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Benchmarking list = l=[[[1],[2]],[[3],[5]],[[6],[6]]]*1000000 (3 million).

In [60]: timeit [sum(i,[]) for i in l]
1.06 s ± 68 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [61]: timeit [[i for i in j] for j in l]
1.13 s ± 64.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [65]: timeit list(starmap(concat, l))
595 ms ± 15.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [71]: timeit list(map(list, map(chain.from_iterable, l)))
1.39 s ± 101 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Ch3steR
  • 20,090
  • 4
  • 28
  • 58
  • 2
    This technique is explained [here](https://stackoverflow.com/a/952946/4518341) – wjandrea Feb 20 '20 at 14:18
  • Could you add options I've offered in your test? – Olvin Roght Feb 20 '20 at 14:42
  • 1
    @OlvinRoght Actually im running your code right now ;) will add it in minute. – Ch3steR Feb 20 '20 at 14:42
  • @Ch3steR, thanks, cause I have no opportunity right now :) – Olvin Roght Feb 20 '20 at 14:43
  • @OlvinRoght Dude your solution is 2 times faster than my solution and r.ook's – Ch3steR Feb 20 '20 at 14:45
  • 1
    @Ch3steR, actually that's what I expected, cause `itertools` is as native as it can be. – Olvin Roght Feb 20 '20 at 14:46
  • @OlvinRoght This solution is a lot slower `result = list(map(lambda x: x[0] + x[1], lists_of_lists))`. I don't remember where I read but It's pretty old stackoverflow answer where it's mentioned `map with lambda` is slower. – Ch3steR Feb 20 '20 at 14:49
  • @Ch3steR, yes that's why I added text in parentheses :D You can try to boost a bit your solution by using [`functools.partial()`](https://docs.python.org/3/library/functools.html#functools.partial) and [`map()`](https://docs.python.org/3/library/functions.html#map) instead of list comprehension. – Olvin Roght Feb 20 '20 at 14:51
  • @OlvinRoght I'm surprised by these results. `list(map(list, map(chain.from_iterable, lists_of_lists)))` is slower than map with lambda. Don't what made it slower. – Ch3steR Feb 20 '20 at 14:53
  • @Ch3steR, it's because casting result into a list every iteration. I have sorted all solutions by expected productivity and now you confirmed that I have had correct expectations :) – Olvin Roght Feb 20 '20 at 14:54
  • @Ch3steR, just for fun, test this `list(map(partial(sum, start=[]), lists_of_lists))`. It's your solution but with functional coding style. – Olvin Roght Feb 20 '20 at 15:00
  • @OlvinRoght It raised `TypeError` saying `sum() takes no keyword arguments`. – Ch3steR Feb 20 '20 at 15:02
  • @Ch3steR, weird, cause I have just launched this code in my console. And [docs](https://docs.python.org/3/library/functions.html#sum) says that it does take this keyword argument. Python 3.8, btw. – Olvin Roght Feb 20 '20 at 15:04
  • @OlvinRoght I ran tests on python3.7 – Ch3steR Feb 20 '20 at 15:06
  • @Ch3steR, ¯\\_(ツ)_/¯ – Olvin Roght Feb 20 '20 at 15:07
0

Try numpy:

In:

import numpy as np
lists_of_lists =np.array([[[1],[2]],[[3],[5]],[[6],[6]]])
lists_of_lists.reshape(lists_of_lists.size//2, 2)

Out:

array([[1, 2],
       [3, 5],
       [6, 6]])
Artur Kasza
  • 356
  • 1
  • 9
0
result = []
for subList in lists_of_lists:
    newList = []
    for subSubList in subList:
        newList.extend(subSubList)
    result.append(newList)

And result contains what is wanted.

Frank-Rene Schäfer
  • 3,182
  • 27
  • 51
0

I hope this is readable

lists_of_lists =[[[1],[2]],[[3],[5]],[[6],[6]]]

def concat_inner(arr):
    return arr[0]+ arr[1]

final_list = list(map(concat_inner, lists_of_lists))

print(final_list)
Henok Teklu
  • 528
  • 3
  • 9
0

You are going completely to the low level. Just go one level less deep and flatten the list there.

lists_of_lists =[[[1],[2]],[[3],[5]],[[6],[6]]]
for i in lists_of_lists:
    flat_list = [item for sublist in i for item in sublist]
    new.append(flat_list)
print(new)
Nirmal Roy
  • 95
  • 1
  • 2
  • 7