Convertir una lista multidimensional a una lista 1D en Python

Una lista multidimensional como l=[[1,2],[3,4]] podría convertir en una 1D haciendo la sum(l,[]) . ¿Alguien puede explicar cómo sucede eso?

Un respondedor dijo que esta técnica solo podría usarse para “aplanar” una lista 2D, que no funcionaría para listas multidimensionales más altas. Pero lo hace, si se repite. Por ejemplo, si A es una lista 3D, la sum (sum (A), []), []) aplanará A a una lista 1D.

sum sum una secuencia usando el operador + . Por ejemplo, sum([1,2,3]) == 6 . El segundo parámetro es un valor de inicio opcional que por defecto es 0. p. Ej. sum([1,2,3], 10) == 16 .

En su ejemplo, hace [] + [1,2] + [3,4] donde + en 2 listas las concatena juntas. Por lo tanto el resultado es [1,2,3,4]

La lista vacía se requiere como el segundo parámetro para sum porque, como se mencionó anteriormente, el valor predeterminado es que la sum agregue a 0 (es decir, 0 + [1,2] + [3,4] ), lo que resultaría en un tipo de operando no compatible ( s) para +: ‘int’ y ‘list’

Esta es la sección relevante de la ayuda para la sum :

sum (secuencia [, inicio]) -> valor

Devuelve la sum de una secuencia de números (NO cadenas) más el valor del parámetro ‘inicio’ (que por defecto es 0).

Nota

Como comenta Wallacoloo, esta no es una solución general para aplanar una lista multidimensional. Simplemente funciona para una lista de listas 1D debido al comportamiento descrito anteriormente.

Actualizar

Para una manera de aplanar 1 nivel de anidamiento, vea esta receta en la página de itertools :

 def flatten(listOfLists): "Flatten one level of nesting" return chain.from_iterable(listOfLists) 

Para aplanar listas más profundamente anidadas (incluidas listas anidadas irregularmente), vea la respuesta aceptada a esta pregunta (también hay otras preguntas vinculadas a la pregunta en sí).

Tenga en cuenta que la receta devuelve un objeto itertools.chain (que es iterable) y la respuesta de la otra pregunta devuelve un objeto generator por lo que debe ajustar cualquiera de estos en una list llamadas si desea obtener la lista completa en lugar de iterar sobre ella. por ejemplo, list(flatten(my_list_of_lists)) .

Si su lista nested es, como usted dice, “2D” (lo que significa que solo desea bajar un nivel y todos los elementos de nivel nested listas nested ), una simple lista de comprensión:

 flat = [x for sublist in nested for x in sublist] 

es el enfoque que recomendaría, mucho más eficiente que la sum (la sum se destina a los números ) fue una molestia para bloquear de alguna manera todos los bashs de “sumr” los no números … Fui el proponente original y el primer implementador de sum en la biblioteca estándar de Python, así que supongo que debería saber ;-).

Si desea bajar “tan profundamente como sea necesario” (para listas profundamente anidadas), la recursión es la forma más simple, aunque al eliminar la recursión puede obtener un mayor rendimiento (al precio de una mayor complicación).

Esta receta sugiere una solución recursiva, una eliminación de la recursión y otros enfoques (todos instructivos, aunque ninguno tan simple como el de una línea que sugerí anteriormente en esta respuesta).

Para cualquier tipo de arreglo multidiamentional, este código se aplanará en una dimensión:

 def flatten(l): try: return flatten(l[0]) + (flatten(l[1:]) if len(l) > 1 else []) if type(l) is list else [l] except IndexError: return [] 

A mi me parece más que estás buscando una respuesta final de:

 [3, 7] 

Para eso estás mejor con una lista de comprensión.

 >>> l=[[1,2],[3,4]] >>> [x+y for x,y in l] [3, 7] 

Escribí un progtwig para hacer aplanamiento multidimensional usando recursión. Si alguien tiene comentarios sobre cómo mejorar el progtwig, siempre puedes verme sonriendo:

 def flatten(l): lf=[] li=[] ll=[] p=0 for i in l: if type(i).__name__=='list': li.append(i) else: lf.append(i) ll=[x for i in li for x in i] lf.extend(ll) for i in lf: if type(i).__name__ =='list': #not completely flattened flatten(lf) else: p=p+1 continue if p==len(lf): print(lf) 

He escrito esta función:

 def make_array_single_dimension(l): l2 = [] for x in l: if type(x).__name__ == "list": l2 += make_array_single_dimension(x) else: l2.append(x) return l2 

¡También funciona!

El operador + concatena las listas y el valor inicial es [] una lista vacía.