Merge nested lists inside list of lists
Question:
I have a very huge list of the format:
a = [[[5],[3]],[[4],[5]],[[6],[7]]]
I want go get each element of my list out of innermost list. Output should be:
output = [[5,3],[4,5],[6,7]]
I tried some methods like reduce(operator.concat, a))
, sum(b, []))
and reduce(lambda x,y: x+y,a)
. But they didn’t generate what I want. I have a large data and I don’t want to use a for loop if possible. Do you know another option for this?
Answers:
This will do:
a = [[x[0][0], x[1][0]] for x in a]
This assumes that there always only 2 elements in each list.
A generic solution would be:
a = [[y[0] for y in x] for x in a]
Flatten each element:
a = [[[5],[3]],[[4],[5]],[[6],[7]]]
output = [[item for subsublist in sublist for item in subsublist] for sublist in a]
You can use itertools.chain
with list comprehension as:
>>> from itertools import chain
>>> a = [[[5],[3]],[[4],[5]],[[6],[7]]]
>>> [list(chain(*l)) for l in a]
[[5, 3], [4, 5], [6, 7]]
Refer "itertools.chain()" documentation for more details.
if I’m understanding your issue properly then the following solution should work.
from functools import reduce
import operator
starting_list = [[[5],[3]],[[4],[5]],[[6]]]
final_list = list(map(lambda x: reduce(operator.concat, x),starting_list))
print(final_list)
from itertools import chain, starmap
from operator import concat
xss = [[[5],[3]],[[4],[5]],[[6],[7]]]
def star(f):
return lambda xs: f(*xs)
print(list(map(star(concat), xss)))
print(list(starmap(concat, xss)))
print([concat(*xs) for xs in xss])
print([list(chain(*xs)) for xs in xss])
Elegant solution has already been pointed out by @moinuddin-quadri. Thought I will add some variety. It is minimal but there is another way.
It can also be solved by chain.from_iterable function, although the solution will read longer. chain.from_iterable is an alternate constructor for chain.
from itertools import chain
a = [[[1],[2]],[[3],[4],[5]],[[6],[7]],[[8],[9],[10],[11]]]
list(map(list,map(chain.from_iterable, a)))
This gives
[[1, 2], [3, 4, 5], [6, 7], [8, 9, 10, 11]]
Both methods are almost comparable in time taken as seen below.
from itertools import chain
import timeit
a = [[[1],[2]],[[3],[4],[5]],[[6],[7]],[[8],[9],[10],[11]]]
def Chain(a):
[list(chain(*l)) for l in a]
def Chain_From_Iterable(a):
list(map(list,map(chain.from_iterable, a)))
print("From chain method: ", timeit.timeit("Chain(a)", number=1000000, globals=globals()))
print("From chain.from_iterable method: ", timeit.timeit("Chain_From_Iterable(a)", number=1000000, globals=globals()))
From chain method: 3.0528709329992125
From chain.from_iterable method: 2.7632316279996303
Following is the output for both of them
I have a very huge list of the format:
a = [[[5],[3]],[[4],[5]],[[6],[7]]]
I want go get each element of my list out of innermost list. Output should be:
output = [[5,3],[4,5],[6,7]]
I tried some methods like reduce(operator.concat, a))
, sum(b, []))
and reduce(lambda x,y: x+y,a)
. But they didn’t generate what I want. I have a large data and I don’t want to use a for loop if possible. Do you know another option for this?
This will do:
a = [[x[0][0], x[1][0]] for x in a]
This assumes that there always only 2 elements in each list.
A generic solution would be:
a = [[y[0] for y in x] for x in a]
Flatten each element:
a = [[[5],[3]],[[4],[5]],[[6],[7]]]
output = [[item for subsublist in sublist for item in subsublist] for sublist in a]
You can use itertools.chain
with list comprehension as:
>>> from itertools import chain
>>> a = [[[5],[3]],[[4],[5]],[[6],[7]]]
>>> [list(chain(*l)) for l in a]
[[5, 3], [4, 5], [6, 7]]
Refer "itertools.chain()" documentation for more details.
if I’m understanding your issue properly then the following solution should work.
from functools import reduce
import operator
starting_list = [[[5],[3]],[[4],[5]],[[6]]]
final_list = list(map(lambda x: reduce(operator.concat, x),starting_list))
print(final_list)
from itertools import chain, starmap
from operator import concat
xss = [[[5],[3]],[[4],[5]],[[6],[7]]]
def star(f):
return lambda xs: f(*xs)
print(list(map(star(concat), xss)))
print(list(starmap(concat, xss)))
print([concat(*xs) for xs in xss])
print([list(chain(*xs)) for xs in xss])
Elegant solution has already been pointed out by @moinuddin-quadri. Thought I will add some variety. It is minimal but there is another way.
It can also be solved by chain.from_iterable function, although the solution will read longer. chain.from_iterable is an alternate constructor for chain.
from itertools import chain
a = [[[1],[2]],[[3],[4],[5]],[[6],[7]],[[8],[9],[10],[11]]]
list(map(list,map(chain.from_iterable, a)))
This gives
[[1, 2], [3, 4, 5], [6, 7], [8, 9, 10, 11]]
Both methods are almost comparable in time taken as seen below.
from itertools import chain
import timeit
a = [[[1],[2]],[[3],[4],[5]],[[6],[7]],[[8],[9],[10],[11]]]
def Chain(a):
[list(chain(*l)) for l in a]
def Chain_From_Iterable(a):
list(map(list,map(chain.from_iterable, a)))
print("From chain method: ", timeit.timeit("Chain(a)", number=1000000, globals=globals()))
print("From chain.from_iterable method: ", timeit.timeit("Chain_From_Iterable(a)", number=1000000, globals=globals()))
From chain method: 3.0528709329992125
From chain.from_iterable method: 2.7632316279996303
Following is the output for both of them