Search code examples
pythonlistrecursionnestedrow

Convert a nested list into rows using python


I am experiencing a scenario where my indigenous recursive implementation program output's a nested list, very similar to a tree. The nested list designed is an abstraction of a complicated structure. What I would require, is to resolve the nested list into many different rows as much as combinations available (optionally implementing recursion).

Previously I tried anytree but my needs are complicated and though good, it was not yielding to my tailored demand. Please do take into account that the nested list is multi-dimensional

input 1

list = [a,b,[c,d]]

output 1

row1 : a,b,c
row2 : a,b,d 

input 2

list = [a,b,[c,[d,[e,f]]]]

output 2

row1 : a,b,c
row2 : a,b,d,e
row3 : a,b,d,f

input 3

list = [a,[b,c],[d,e]]

output 3

row1 : a,b,d
row2 : a,b,e
row3 : a,c,d
row4 : a,c,e

1. Rows in output is for representaional purposes only, output can sure be a list with many elements

2. a,b,c,d,etc are objects

I do independent research concerning Indic languages, so couldn't find a better way to implement a pivotal recursion output than a nested list. Also feel free to suggest any alternatives to the nested list representation that suits the purpose of obtaining the output in an easier way if you do have one.


Solution

  • You can use recursion with itertools.product:

    import itertools as it
    def flatten(d, s = False):
       if not s:
          l = [[i] if not isinstance(i, list) else flatten(i, True) for i in d]
          yield from it.product(*l)
       else:
          for i in d:
             if not isinstance(i, list):
                yield i
             else:
                yield from flatten(i, False)
    
    def form_t(d):
       for i in d:
         if not isinstance(i, tuple):
            yield i
         else:
            yield from form_t(i)
    
    all_lists = [['a', 'b', ['c', 'd']], ['a', 'b', ['c', ['d', ['e', 'f']]]], ['a', ['b', 'c'], ['d', 'e']]]
    for i in all_lists:
       print([tuple(form_t(j)) for j in flatten(i)])
    

    Output:

    [('a', 'b', 'c'), ('a', 'b', 'd')]
    [('a', 'b', 'c'), ('a', 'b', 'd', 'e'), ('a', 'b', 'd', 'f')]
    [('a', 'b', 'd'), ('a', 'b', 'e'), ('a', 'c', 'd'), ('a', 'c', 'e')]