2011-05-10 17 views
8

yo no tengo experiencia en Python, y yo a menudo escribir código que (simplificado) tiene el siguiente aspecto:¿Cómo puedo usar una lista de comprensión para extender una lista en python?

accumulationList = [] 
for x in originalList: 
    y = doSomething(x) 
    accumulationList.append(y) 
return accumulationList 

Luego, después pasa a mi prueba, me refactorizar a

return [doSomething(x) for x in originalList] 

Pero supongamos que resulta un poco diferente, y mi bucle se ve así:

accumulationList = [] 
for x in originalList: 
    y = doSomething(x) 
    accumulationList.extend(y) 
return accumulationList 

donde la lista doSomething devuelve una lista. ¿Cuál es la forma más pitonica de lograr esto? Obviamente, la lista anterior de comprensión daría una lista de listas.

Respuesta

4

mucho más simple y más limpio, con comprensión de lista:

[y for x in originalList for y in doSomething(x)] 
+1

¡Gran mejora! Cuando hice la pregunta, no me hubiera gustado usar una lista anidada de comprensión. –

4

¿Te refieres a algo como esto?

accumulationList = [] 
for x in originalList: 
    accumulationList.extend(doSomething(x)) 
return accumulationList 

o más corto código (pero no óptimo):

return sum((doSomething(x) for x in originalList), []) 

o el mismo:

return sum(map(doSomething, originalList), []) 

Gracias a @eyquem por la pista (si se utiliza Python 2.x):

import itertools as it 

return sum(it.imap(doSomething, originalList), []) 
+1

'' suma de retorno (mapa (doSomething, originalList)), []) '' mejor con IMAP ** * * si Python 2. Derecha si Python 3 – eyquem

2

Python's in-place add operator (), disponible como iadd en el módulo operator) es equivalente a .extend para la lista. Vincúlelo con reduce para obtener lo que desea.

import operator 

reduce(operator.iadd, (doSomething(x) for x in originalList) 
, accumulation_list) 
0

No creo que haya una sintaxis especial para este caso. Pero usted podría hacer el bucle más corto:

accumulationList += doSomething(x) 

Si insiste, se puede utilizar la programación funcional para aplanar la lista:

result = reduce(lambda a,b: a+b, [[i,i*2] for i in range(3)]) 

Pero yo no diría que este Pythonic, creo que es más duro para leer que para un bucle for.

2

Creo que las respuestas que implican add o iadd se ejecutan en tiempo cuadrático, lo que probablemente no sea bueno. Me gustaría probar:

from itertools import chain 
accumulation_list = list(chain.from_iterable(doSomething(x) for x in originalList)) 
Cuestiones relacionadas