Acabo de empezar a jugar con Python, así que ten paciencia 🙂
Supongamos la siguiente lista que contiene listas anidadas:
[[[[[1, 3, 4, 5]], [1, 3, 8]], [[1, 7, 8]]], [[[6, 7, 8]]], [9]]
En una representación diferente:
[ [ [ [ [1, 3, 4, 5] ], [1, 3, 8] ], [ [1, 7, 8] ] ], [ [ [6, 7, 8] ] ], [9] ]
¿Cómo haría para extraer esas listas internas para que se devuelva un resultado con el siguiente formulario:
[[1, 3, 4, 5], [1, 3, 8], [1, 7, 8], [6, 7, 8], [9]]
¡Muchas gracias!
EDITAR (Gracias @falsetru):
Las listas vacías de lista interna o de tipo mixto nunca serán parte de la entrada.
Esto parece funcionar, suponiendo que no haya listas ‘mixtas’ como [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
Salida de la list(get_inner(nested_list))
:
[[1, 3, 4, 5], [1, 3, 8], [1, 7, 8], [6, 7, 8], [9]]
O incluso más corto, sin generadores, utilizando la sum
para combinar las listas resultantes:
def get_inner(nested): if all(type(x) == list for x in nested): return sum(map(get_inner, nested), []) return [nested]
Usando 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,
se utiliza isinstance(xs[0], list)
lugar de all(isinstance(x, list) for x in xs)
, porque no hay una lista mixta / lista interna vacía.
>>> 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]]
Más eficiente que la recursión:
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)