¿Múltiples enunciados en la lista de composiciones en Python?

¿Es posible tener algo como:

list1 = ... currentValue = 0 list2 = [currentValue += i, i for i in list1] 

Lo intenté pero no funcionó? ¿Cuál es la syntax adecuada para escribir esos?

EDIT: la statement de impresión fue un ejemplo. En realidad estoy incrementando un valor fuera del bucle.

Las declaraciones no pueden ir dentro de expresiones en Python; fue una complicación que fue deliberadamente diseñada fuera del lenguaje. Para este problema, intente usar una complicación que lo hizo en el lenguaje: generadores. Reloj:

 def total_and_item(sequence): total = 0 for i in sequence: total += i yield (total, i) list2 = list(total_and_item(list1)) 

El generador mantiene una cuenta stream de los elementos vistos hasta ahora, y los coloca como prefijo en cada elemento, tal como parece que intenta hacer el ejemplo. Por supuesto, un bucle directo podría ser incluso más simple, ¡eso crea una lista vacía en la parte superior y simplemente llama a append () mucho! 🙂

No estoy muy seguro de lo que estás tratando de hacer, pero probablemente sea algo como

 list2 = [(i, i*2, i) for i in list1] print list2 

La statement en la lista de comprensión debe ser una sola statement, pero siempre se puede hacer una llamada de función:

 def foo(i): print i print i * 2 return i list2 = [foo(i) for i in list1] 

Aquí hay un ejemplo de otra pregunta :

 [i for i,x in enumerate(testlist) if x == 1] 

el generador de enumeración devuelve una tupla de 2 que entra en i, x.

Como dijo pjz, puedes usar funciones, así que aquí puedes usar un cierre para hacer un seguimiento del valor del contador:

 # defines a closure to enclose the sum variable def make_counter(init_value=0): sum = [init_value] def inc(x=0): sum[0] += x return sum[0] return inc 

Entonces haces lo que quieres con list1:

 list1 = range(5) # list1 = [0, 1, 2, 3, 4] 

Y ahora con solo dos líneas, obtenemos list2:

 counter = make_counter(10) # counter with initial value of 10 list2 = reduce(operator.add, ([counter(x), x] for x in list1)) 

Al final, list2 contiene:

 [10, 0, 11, 1, 13, 2, 16, 3, 20, 4] 

que es lo que quería, y puede obtener el valor del contador después del bucle con una llamada:

 counter() # value is 20 

Finalmente, puede reemplazar el material de cierre por cualquier tipo de operación que desee, aquí tenemos un incremento, pero depende de usted. Tenga en cuenta también que utilizamos una lista de reducir para aplanar2, y este pequeño truco requiere que importe el operador antes de llamar a la línea con la reducción:

 import operator 

En primer lugar, es probable que no desee utilizar la print . No devuelve nada, así que use un bucle for convencional si solo quiere imprimir cosas. Lo que buscas es:

 >>> list1 = (1,2,3,4) >>> list2 = [(i, i*2) for i in list1] # Notice the braces around both items >>> print(list2) [(1, 2), (2, 4), (3, 6), (4, 8)] 

Imprimir es una cosa rara de llamar en una lista de comprensión. Ayudaría si nos mostrara qué salida desea, no solo el código que no funciona.

Aquí hay dos conjeturas para usted. De cualquier manera, el punto importante es que la statement de valor en una lista de comprensión debe ser un valor único . No puede insertar varios elementos a la vez. (Si eso es lo que estás tratando de hacer, salta al segundo ejemplo).

 list1 = [1, 2, 3] list2 = [(i, i*2, i) for i in list1] # list2 = [(1, 2, 1), (2, 4, 2), (3, 6, 3)] 

Para obtener una lista plana:

 list1 = [1, 2, 3] tmp = [(i, i*2) for i in list1] list2 = [] map(list2.extend, tmp) # list2 = [1, 2, 1, 2, 4, 2, 3, 6, 3] 

Edición: Incrementar un valor en medio de la comprensión de la lista es aún extraño. Si realmente necesita hacerlo, es mejor que escriba un bucle regular para, y agregue valores a medida que avanza. En Python, la astucia de este tipo casi siempre se califica como “antiptona”. Hágalo si es necesario, pero no tendrá fin de críticas en foros como este. 😉

Para su ejemplo editado:

 currentValue += sum(list1) 

o:

 for x in list1: currentValue += x 

Las comprensiones de listas son geniales, me encantan, pero no hay nada de malo en el bucle de humble for y no debes tener miedo de usarlo 🙂

EDITAR: “Pero, ¿qué pasa si quiero incrementar diferente a los valores recostackdos?”

Bueno, ¿qué quieres incrementar? Tienes todo el poder de python a tus ordenes!

¿Incremento por x-cuadrado?

 for x in list1: currentValue += x**2 

¿Incrementar por alguna función de x y su posición en la lista?

 for i, x in enumerate(list1): currentValue += i*x 

¿Por qué crearías una lista duplicada? Parece que todo lo que haría esa lista de comprensión es simplemente sumr los contenidos.

¿Por qué no solo?

 list2 = list(list1) #this makes a copy currentValue = sum(list2) 

No puede hacer varias declaraciones, pero puede hacer una llamada de función. Para hacer lo que parece querer arriba, podrías hacer:

 list1 = ... list2 = [ (sum(list1[:i], i) for i in list1 ] 

en general, dado que las comprensiones de listas son parte de la parte ‘funcional’ de python, estás restringido a … funciones. Otras personas han sugerido que puedes escribir tus propias funciones si es necesario, y esa también es una sugerencia válida.