2

Having this list

l = [['a', 'b', 'c', 'd'],[[["d","d"]],['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]]

I would like to get a function extracting all nested lists and return

l = [['a', 'b', 'c', 'd'],["d","d"],['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]

like flatten but keeping the list formation of every nested list. This is the closest I have been and I feel like there is a way of accomplishing my goal without using an extra structure to filter duplicates. Also, order matters in string and list level.

def get_all_nested_list(l,returned_list):
    nested_list = l
    while isinstance(nested_list, list):
        for elem in nested_list:
            get_all_nested_list(elem,returned_list)
        if isinstance(nested_list[0], str):
            returned_list.append(nested_list)
        nested_list = nested_list[0]


if __name__ == '__main__':
    l = [['a', 'b', 'c', 'd'],[[["d","d"]],['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]]
    l2 = []
    get_all_nested_list(l,l2)
    print(l2)

Any other ways of doing it the above either by using itertools or suggesting an actually proper way of using yield instead of passing another list as argument are more than welcome.

4
  • This looks like a good case for more_itertools.collapse() more-itertools.readthedocs.io/en/stable/… Commented Feb 22, 2020 at 5:27
  • 1
    The answer to this question is here: How to remove all unnecessary arrays in nd array . I remember because I wrote a recursive function in a hurry for the answer but the end accepted solution was far better and I kicked myself for not thinking of it first. Commented Feb 22, 2020 at 5:32
  • @RahulP It fails since lists are of different nested levels. It returns [['a', 'b', 'c', 'd'], [[['d', 'd']], ['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]] Commented Feb 22, 2020 at 14:23
  • @AutomaticStatic I am not sure how someone can implement it with this function since the lists are of different nested levels which is the primary reason I posted this question. Commented Feb 22, 2020 at 14:55

2 Answers 2

4

You could try a recursive function

my_nested_list = [['a', 'b', 'c', 'd'],[[["d","d"]],['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]]

def flatten(nested_list):
    for item in nested_list:
        if not isinstance(item[0],list):
            yield item
        else:
            yield from flatten(item)

flat_list = [item for item in flatten(my_nested_list)]
print(flat_list)
Sign up to request clarification or add additional context in comments.

4 Comments

recursion in a generator. I like it.
In case my_nested_list = [['a', 'b', 'c', 'd'],['e', [["d","d"]],['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]], this code gives [['a', 'b', 'c', 'd'], ['e', [['d', 'd']], ['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]]. Right?
ONE QUESTION:: In the above case, Is THIS CODE correct?
@TopDeveloper I didn't explicitly state it but every element supposed to be a list. My bad, my question's specifications were not strict enough. That's because I change completely implementation in my program and didn't have to use lists but I still have the query which I posted. The code above is not particularly wrong for my not so specific request.
1

You can do it like this:

from itertools import chain 

my_nested_list = [['a', 'b', 'c', 'd'],['e', ['r'], [["d","d"]],['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]]

def flatten(nested_list):
    for item in nested_list:
        if not isinstance(item,list):
            yield item
        elif list(chain(*item)) == item:
            yield item
        else:
            yield from flatten(item)

flat_list = list(flatten(my_nested_list))
# [['a', 'b', 'c', 'd'], 'e', ['r'], ['d', 'd'], ['z', 'x', 'g', 'd'], ['z', 'C', 'G', 'd']]

Thanks

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.