Roi Tal
Roi Tal

Reputation: 1000

Python - Extracting inner most lists

Just started toying around with Python so please bear with me :)

Assume the following list which contains nested lists:

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

In a different representation:

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

How would you go about extracting those inner lists so that a result with the following form would be returned:

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

Many thanks!

EDIT (Thanks @falsetru):

Empty inner-list or mixed type lists will never be part of the input.

Upvotes: 23

Views: 1967

Answers (3)

tobias_k
tobias_k

Reputation: 82929

This seems to work, assuming no 'mixed' lists like [1,2,[3]]:

def get_inner(nested):
    if all(type(x) == list for x in nested):
        for x in nested:
            for y in get_inner(x):
                yield y
    else:
        yield nested

Output of list(get_inner(nested_list)):

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

Or even shorter, without generators, using sum to combine the resulting lists:

def get_inner(nested):
    if all(type(x) == list for x in nested):
        return sum(map(get_inner, nested), [])
    return [nested]

Upvotes: 33

user278064
user278064

Reputation: 10180

More efficient than recursion:

result = []
while lst:
    l = lst.pop(0)
    if type(l[0]) == list:
        lst += [sublst for sublst in l if sublst] # skip empty lists []
    else:
        result.insert(0, l) 

Upvotes: 5

falsetru
falsetru

Reputation: 369194

Using itertools.chain.from_iterable:

from itertools import chain

def get_inner_lists(xs):
    if isinstance(xs[0], list): # OR all(isinstance(x, list) for x in xs)
        return chain.from_iterable(map(get_inner_lists, xs))
    return xs,

used isinstance(xs[0], list) instead of all(isinstance(x, list) for x in xs), because there's no mixed list / empty inner list.


>>> list(get_inner_lists([[[[[1, 3, 4, 5]], [1, 3, 8]], [[1, 7, 8]]], [[[6, 7, 8]]], [9]]))
[[1, 3, 4, 5], [1, 3, 8], [1, 7, 8], [6, 7, 8], [9]]

Upvotes: 13

Related Questions