2012-04-14 5 views
15

Tengo 2 bucles para y quiero mejorarlo como la comprensión de listas o lambda o de lo contrario. ¿cómo puedo lograr lo mismo?escriba el mejor código en lugar de 2 para los bucles

por ejemplo:

filename = ['a.txt', 'b.txt', 'c.txt'] 
for files in filename: 
    for f in glob.glob(os.path.join(source_path, files)): 
     print f 
     ... some processing... 
+0

Lo recomiendo primero para asegurarse de que realmente lo necesita. Por ejemplo, la guía de estilo de Google Python sugiere que su código está bien tal como está (aquí hay una parte sobre [la lista de comprensiones] (http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=List_Comprehensions#List_Comprehensions).), las funciones lambda están debajo). – Tony

Respuesta

27

Su código es perfectamente bien como está. Solo puede hacerlo menos legible introduciendo construcciones complejas innecesarias.

+0

@thebjom: ¿puedes explicar qué construcciones complejas innecesarias? – sam

+2

Ni las listas de comprensión ni las lambdas mejorarán la claridad de ese código, por lo tanto, solo están agregando complejidad. Hay, por supuesto, situaciones donde pueden aclarar las cosas, pero este no es uno de esos momentos. – thebjorn

+3

+1. Y, Pythonic == English. A veces no tienes más remedio que escribir usando 2, 3 o incluso 4 bucles anidados porque es difícil de usar o lambda. Y molestar con estilo puede llevarte para siempre para depurar y escribir documentación. – CppLearner

4

Puede comprimir los dos for bucles en un solo generator expression *, con un nuevo bucle for para extraer los nombres de archivo de él.

for f in (f_ for files in filename 
      for f_ in glob.glob(os.path.join(source_path, files))): 
    print f 
    # ... 

Como dijo la otra respuesta, esto es no mejor, esto es peor y no se debe utilizar (no estoy seguro de que sea suficiente énfasis!) Es mucho más difícil entender lo que está sucediendo, y probablemente tenga un pequeño beneficio en el rendimiento (de hecho, las capas adicionales de indirección significan que es probable que sea más lento).

(* básicamente equivalente a una lista por comprensión, pero mejor en situaciones como esta.)

2

expresión largo es difícil de leer cuando se tiene que escanear a la espalda derecha y redonda. es aún peor cuando hay muchas variables locales, lambdas y comprensiones, meramente separadas por pares y comas, en pocas líneas. Úselos solo si su código no es más largo y más complejo.
Para su caso, prefiero extraer find como una compensación. Pero tal como decía la respuesta principal, tu código es lo suficientemente bueno.

from itertools import chain 

find = lambda p: glob.glob(os.path.join(source_path, p)) 
for file in chain(map(find, filename)): 
    """ 
    =) I like one-level indentation here. 
    =(I don't know which file pattern is used currently, 
     unless I use longer expression... 
    """ 
4

Lo haría como a continuación. La razón es que ahora puedes separar la formación del patrón de búsqueda, la búsqueda y la elaboración de archivos. Es más fácil expandirse si no están relacionados.

Si su sistema es un poco exótico (por ejemplo, unidad de red distribuida), la línea con ambos glob y os.path.join es una línea desagradable. Aunque, como han mencionado otros, dos bucles están perfectamente bien.

filename = ['a.txt', 'b.txt', 'c.txt'] 

searchPatterns = [os.path.join(source_path, files) for files in filename] 

searchResults = [glob.glob(pattern) for pattern in searchPatterns] 

fileListFlat = sum(searchResults,[]) 

for file in fileListFlat: 
    print file 
Cuestiones relacionadas