Pregunta

Para mí, la comprensión de listas parece ser como el bloque opaco de granito que son para mí las expresiones regulares.Necesito consejos.

Digamos que tengo una lista 2D:

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

Me gustaría fusionar esto en una lista larga.

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.

¿Fue útil?

Solución

Al igual que:

[ item for innerlist in outerlist for item in innerlist ]

Convirtiendo 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.Aunque el "cuerpo" del bucle está al inicio de la lista de compilación, el orden de los bucles anidados (y las cláusulas 'if') sigue siendo el mismo que cuando escribirías el bucle:

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

Otros consejos

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.
Las ys provienen de las xs.
Las xs vienen de li.

Para mapear eso en una cadena:

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

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

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

Alternativamente, puede utilizar el itertools del módulo chain función, 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 producir 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:usar sum en lugar de reduce, (gracias Thomas Wouters!)

Para convertirla en una lista aplanada, utilice:

  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 hacerlo:

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

Para el primero, puedes usar join 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 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"

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

EDITAR :Es curioso, estoy aprendiendo muchas formas de hacerlo.¿Quién dijo que sólo había una buena manera de hacerlo?

Hay muchas maneras de resolver este problema.Me gusta numpy's herramientas porque normalmente ya está importado en todo lo que hago.Sin embargo, si no estás usando Numpy para nada más, 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<len(li):
    li2=numpy.concatenate((li2,li[i]))
    i+=1
print li2

Esto imprimiría [0 1 2 3 4 5 6 7 8] y luego también podrás convertir esto en tu cadena.

import itertools
itertools.flatten( li )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top