3

I get a nested list as input.
Simplified version is as under.

myList=[[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]

I wish to unpack it into a simple list of lists.
I can do like this--

    simpleList=[]
    for i in myList:
        for j in i:
            simpleList.append(j)

As desired, the simpleList is

[[1, 2, 3], [4, 5, 6], [2, 3, 4], [3, 4, 5], [4, 6, 7], [5, 7, 9]]

My question:-
What I did was, maybe, a beginner's coding approach.
Is there a more professional, efficient (and pythonic) approach to unpack this nested list?
Thanks.

EDIT:-
My method doesn't work for deeply nested lists.
e.g. [[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]],[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9],[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]]
pl. refer to the comments to answers.

Vineet
  • 624
  • 1
  • 11
  • 26
  • 1
    `sum(myList, [])`, but `itertools.chain` based solution will be more efficient – Faibbus Apr 18 '18 at 13:34
  • 6
    Possible duplicate of [Making a flat list out of list of lists in Python](https://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python) – Chris_Rands Apr 18 '18 at 13:35

3 Answers3

4

Use chain from itertools

from itertools import chain
myList=[[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]
print(list(chain.from_iterable(myList)))   #print(list(chain(*myList)))

Output:

[[1, 2, 3], [4, 5, 6], [2, 3, 4], [3, 4, 5], [4, 6, 7], [5, 7, 9]]
Rakesh
  • 81,458
  • 17
  • 76
  • 113
2

You can do this using a recursive function in order to solve nested list with any depth.

def unwrap_list(mylist, result):
   if any(isinstance(i, list) for i in mylist):
      for value in mylist:
         unwrap_list(value, result)
   else:
      result.append(mylist)

mylist = [[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]
result = []
unwrap_list(mylist, result)
print(result)

Another approach is using a generator.

def flatten(L):
    for item in L:
        if any(isinstance(i, list) for i in item):
          yield from flatten(item)
        else:
          yield item
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
  • yes, this can solve the task. But as the python idiom says -- "simple is better than complex", lambda or chain approach can do this in one liner. Maybe, there is any performance benefit by your suggested solution. Kindly advise. Thanks. – Vineet Apr 18 '18 at 14:02
  • 1
    @Vineet, there is no performance benefit, but it seems that for following example other answers don't work: `[[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]],[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9],[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]]` – Mihai Alexandru-Ionut Apr 18 '18 at 14:10
  • Great @Mihai Alexandru-Ionut . Your method addresses the question most appropriately. I have accepted this answer. Thanks. – Vineet Apr 19 '18 at 03:33
  • Maybe, the lambda or chain approaches can be modified in a way it solves the problem. Can you pl. share your knowledge on that? Thanks. – Vineet Apr 19 '18 at 03:36
  • 1
    @Vineet, I tried answers from https://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python , but it seems that you have to use recursion to lists with any depth. – Mihai Alexandru-Ionut Apr 19 '18 at 07:38
  • 1
    I too tried some answers from that thread, but with erroneous result. I better stick to recursion for deeply nested lists. Thanks. – Vineet Apr 19 '18 at 07:48
1
myList=[[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]
reduce(lambda x, y: x+y, myList)

Output:

[[1, 2, 3], [4, 5, 6], [2, 3, 4], [3, 4, 5], [4, 6, 7], [5, 7, 9]]
Nishant Nawarkhede
  • 8,234
  • 12
  • 59
  • 81
  • As @Mihai Alexandru-Ionut rightly pointed out, this solution doesn't work with [[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]],[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9],[[1,2,3],[4,5,6]],[[2,3,4],[3,4,5]],[[4,6,7],[5,7,9]]]] – Vineet Apr 19 '18 at 03:32