Подтвердить что ты не робот

Python - извлечение внутренних списков

Просто начал играть с Python, поэтому, пожалуйста, несите меня:)

Предположим, что следующий список содержит вложенные списки:

[[[[[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]
]

Как вы могли бы извлечь эти внутренние списки, чтобы получить результат со следующей формой:

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

Большое спасибо!

EDIT (Спасибо @falsetru):

Пустые списки внутреннего списка или смешанного типа никогда не будут частью ввода.

4b9b3361

Ответ 1

Это, похоже, работает, не допуская "смешанных" списков, таких как [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

Вывод list(get_inner(nested_list)):

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

Или даже короче, без генераторов, используя sum, чтобы объединить результирующие списки:

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

Ответ 2

Используя 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,

используется isinstance(xs[0], list) вместо all(isinstance(x, list) for x in xs), потому что нет смешанного списка/пустой внутренний список.


>>> 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]]

Ответ 3

Более эффективен, чем рекурсия:

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)