Aplanar una lista de listas irregulares (anidadas arbitrariamente)

Resuelto telliott99 asked hace 14 años • 53 respuestas

Sí, sé que este tema se ha tratado antes:

  • ¿Idioma de Python para encadenar (aplanar) un iterable infinito de iterables finitos?
  • Aplanar una lista poco profunda en Python
  • ¿Comprensión para aplanar una secuencia de secuencias?
  • ¿Cómo hago una lista plana a partir de una lista de listas?

pero hasta donde yo sé, todas las soluciones, excepto una, fallan en una lista como [[[1, 2, 3], [4, 5]], 6], donde está el resultado deseado [1, 2, 3, 4, 5, 6](o quizás incluso mejor, un iterador).

La única solución que vi que funciona para un anidamiento arbitrario se encuentra en esta pregunta :

def flatten(x):
    result = []
    for el in x:
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

¿Es este el mejor enfoque? ¿Pasé por alto algo? ¿Algún problema?

telliott99 avatar Jan 29 '10 05:01 telliott99
Aceptado

El uso de funciones de generador puede hacer que su ejemplo sea más fácil de leer y mejorar el rendimiento.

Pitón 2

Usando el IterableABC agregado en 2.6:

from collections import Iterable

def flatten(xs):
    for x in xs:
        if isinstance(x, Iterable) and not isinstance(x, basestring):
            for item in flatten(x):
                yield item
        else:
            yield x

Pitón 3

En Python 3, basestringya no existe, pero la tupla (str, bytes)da el mismo efecto. Además, el yield fromoperador devuelve un artículo de un generador uno por uno.

from collections.abc import Iterable

def flatten(xs):
    for x in xs:
        if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
            yield from flatten(x)
        else:
            yield x
Cristian avatar Jan 28 '2010 22:01 Cristian

Mi solución:

import collections


def flatten(x):
    if isinstance(x, collections.Iterable):
        return [a for i in x for a in flatten(i)]
    else:
        return [x]

Un poco más conciso, pero más o menos igual.

Josh Lee avatar Jan 28 '2010 22:01 Josh Lee