Aplanar una lista, el proceso de convertir una lista anidada en una lista de un solo nivel, es una tarea común en Python. Este artículo explora varias técnicas para lograr esto, clasificándolas por su profundidad de aplanamiento: superficial y profunda.
Tabla de contenido
Aplanamiento superficial
El aplanamiento superficial solo elimina un nivel de anidamiento. Es ideal cuando se tiene una lista de listas, pero esas listas internas no contienen estructuras anidadas adicionales. Existen dos métodos eficientes:
List Comprehension: Esta proporciona una solución concisa y legible:
nested_list = [[1, 2, 3], [4, 5], [6]]
flat_list = [item for sublist in nested_list for item in sublist]
print(flat_list) # Salida: [1, 2, 3, 4, 5, 6]
itertools.chain.from_iterable
: Para listas más grandes, este enfoque ofrece un mejor rendimiento debido a su iteración optimizada:
from itertools import chain
nested_list = [[1, 2, 3], [4, 5], [6]]
flat_list = list(chain.from_iterable(nested_list))
print(flat_list) # Salida: [1, 2, 3, 4, 5, 6]
Limitaciones: El aplanamiento superficial no logra aplanar completamente las listas con listas anidadas dentro de listas anidadas. Por ejemplo:
nested_list = [[1, 2, [3, 4]], [5, 6]]
flat_list = [item for sublist in nested_list for item in sublist]
print(flat_list) # Salida: [1, 2, [3, 4], 5, 6]
La lista interna [3, 4]
permanece anidada.
Aplanamiento profundo
El aplanamiento profundo maneja recursivamente listas anidadas de cualquier profundidad. Existen dos enfoques principales:
Función recursiva: Esta elegante solución utiliza la recursión para recorrer la estructura anidada:
def flatten(nested_list):
flat_list = []
for item in nested_list:
if isinstance(item, list):
flat_list.extend(flatten(item))
else:
flat_list.append(item)
return flat_list
nested_list = [[1, 2, [3, 4]], [5, 6, [7, [8, 9]]]]
flat_list = flatten(nested_list)
print(flat_list) # Salida: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Enfoque iterativo (usando una pila): La recursión puede provocar errores de desbordamiento de pila con anidamiento extremadamente profundo. Un enfoque iterativo que utiliza una pila proporciona robustez:
def flatten_iterative(nested_list):
flat_list = []
stack = [nested_list]
while stack:
current = stack.pop()
if isinstance(current, list):
stack.extend(current)
else:
flat_list.append(current)
return flat_list
nested_list = [[1, 2, [3, 4]], [5, 6, [7, [8, 9]]]]
flat_list = flatten_iterative(nested_list)
print(flat_list) # Salida: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Conclusión
La elección entre el aplanamiento superficial y el profundo depende completamente de la estructura de sus listas anidadas. El aplanamiento superficial es suficiente para el anidamiento de un solo nivel y ofrece soluciones concisas y eficientes. Sin embargo, para listas anidadas arbitrariamente, es necesario el aplanamiento profundo, preferiblemente utilizando el enfoque iterativo basado en pila para mayor robustez.