¿Cómo fusiono una matriz 2D en Python en una cadena con List Comprehension?

La comprensión de lista para mí parece ser como el bloque opaco de granito que las expresiones regulares son para mí. Necesito punteros.

Digamos, tengo una lista 2D:

li = [[0,1,2],[3,4,5],[6,7,8]] 

Me gustaría fusionar esto en una larga lista

 li2 = [0,1,2,3,4,5,6,7,8] 

o en una cadena con separadores:

 s = "0,1,2,3,4,5,6,7,8" 

Realmente, me gustaría saber cómo hacer ambas cosas.

Related of "¿Cómo fusiono una matriz 2D en Python en una cadena con List Comprehension?"

Al igual que:

 [ item for innerlist in outerlist for item in innerlist ] 

Convertir eso directamente en una cadena con separadores:

 ','.join(str(item) for innerlist in outerlist for item in innerlist) 

Sí, el orden de ‘para lista interna en lista externa’ y ‘para elemento en lista interna’ es correcto. A pesar de que el “cuerpo” del bucle está al comienzo de la lista comp, el orden de los bucles nesteds (y las cláusulas ‘if’) sigue siendo el mismo que cuando escribiría el bucle:

 for innerlist in outerlist: for item in innerlist: ... 

Trata eso:

 li=[[0,1,2],[3,4,5],[6,7,8]] li2 = [ y for x in li for y in x] 

Puedes leerlo así:
Dame la lista de cada ys.
Los ys provienen de los xs.
Los x vienen de li.

Para mapear eso en una cadena:

 ','.join(map(str,li2)) 

Hay un par de opciones. Primero, puedes crear una nueva lista y agregarle el contenido de cada lista:

 li2 = [] for sublist in li: li2.extend(sublist) 

Alternativamente, puede usar la itertools de chain del módulo itertools , que produce un iterable que contiene todos los elementos en múltiples iterables:

 import itertools li2 = list(itertools.chain(*li)) 

Si adopta este enfoque, puede generar la cadena sin crear una lista intermedia:

 s = ",".join(itertools.chain(*li)) 

Mi favorito, y el más corto, es este:

 li2 = sum(li, []) 

y

 s = ','.join(li2) 

EDITAR: utilizar la sum lugar de reduce , (gracias Thomas Wouters !)

Para hacer una lista aplanada, use:

  1. http://code.activestate.com/recipes/121294/
  2. http://code.activestate.com/recipes/363051/

Entonces, join para convertirlo en una cuerda.

Para el segundo, hay un método de cadena incorporado para hacer eso:

 >>> print ','.join(str(x) for x in li2) "0,1,2,3,4,5,6,7,8" 

Para la primera, puede usar unirse dentro de una lista de comprensión:

 >>> print ",".join([",".join(str(x) for x in li]) "0,1,2,3,4,5,6,7,8" 

Pero es más fácil de usar itertools.flatten:

 >>> import itertools >>> print itertools.flatten(li) [0,1,2,3,4,5,6,7,8] >>> print ",".join(str(x) for x in itertools.flatten(li)) "0,1,2,3,4,5,6,7,8" 

NB: itertools es un módulo que lo ayuda a lidiar con tareas comunes con iteradores como lista, tuplas o cadena … Es útil porque no almacena una copia de la estructura en la que está trabajando, sino que procesa los elementos uno por uno. .

EDIT: divertido, estoy aprendiendo muchas maneras de hacerlo. ¿Quién dijo que solo había una buena manera de hacerlo?

Hay muchas maneras de hacer este problema. Me gustan las herramientas de Numpy porque normalmente ya se importa en todo lo que hago. Sin embargo, si no está utilizando Numpy para otra cosa, probablemente este no sea un buen método.

 import numpy li = [[0,1,2],[3,4,5],[6,7,8]] li2=li[0] #first element of array to merge i=1 while i 

Esto imprimirá [0 1 2 3 4 5 6 7 8] y luego puede convertir esto en su cadena también.

 import itertools itertools.flatten( li )