Home > Back-end >  Get all elements of nested lists with recursion
Get all elements of nested lists with recursion

Time:05-22

~ from This Edabit Challenge ~

I need to get all the elements of nested lists and put them all in one list using recursion.

My code below prints out each element, but how do I save them all to one list and return them?

It has to be kept in the scope of the function. I can't add a global list and append all of them. It works technically, but it doesn't work for the challenge I'm trying to pass.

I printed the values out (which is var x in the code) because that shows me that I'm getting close (I think). I just need a way to return the values back to my function and have it append it to the list that I will eventually return.

Examples:
flatten([[[[[["direction"], [372], ["one"], [[[[[["Era"]]]], "Sruth", 3337]]], "First"]]]]) ➞ ["direction", 372, "one", "Era", "Sruth", 3337, "First"]

flatten([[4666], [5394], [466], [[["Saskia", [[[[["DXTD"]], "Lexi"]]]]]]]) ➞ [4666, 5394, 466, "Saskia", "DXTD", "Lexi"]

Code:

    def flatten(arr):   
        
        res = [] 
        if isinstance(arr, list):
            for i in arr:
                res.append(flatten(i))
        else:
            return arr
        if isinstance(res, list):
            for i in res:
                x = flatten(i)
                if x:
                    print(x)
            
    
    
    x = flatten([[[[[["direction"], [372], ["one"], [[[[[["Era"]]]], "Sruth", 3337]]], "First"]]]])
    print(main)

outputs :

    direction
    372
    one
    Era
    Sruth
    3337
    First
    []

The output above shows that my code goes through every non-list value.

CodePudding user response:

I would like to offer two solutions: the first uses recursion and the second uses a queue.

First solution

def flatten_helper(nested):
    for e in nested:
        if isinstance(e, list):
            yield from flatten_helper(e)
        else:
            yield e
            
def flatten(nested):
    return list(flatten_helper(nested))

The flatten_helper function is a generator, which generates a list of elements that are not a list. If an element is a list, we call flatten_helper again until we get non-list elements.

Second solution

import collections

def flatten(nested):
    queue = collections.deque(nested)
    out = []
    while queue:
        e = queue.popleft()
        if isinstance(e, list):
            queue.extendleft(reversed(e))
        else:
            out.append(e)
    return out

In this solution, we loop through the nested list. If the element is a list, we place each sub element into a queue for later processing. If the element is not a list, we append it to out.

CodePudding user response:

Pass a list to flatten, and append to it at each step:

def flatten(arr, list_):
    if isinstance(arr, list):
        for i in arr:
            flatten(i, list_)
    else:
        list_.append(arr)

test = [['a'], 'b']
output = []
flatten(test, output)
output

['a', 'b']

  • Related