Python: uso de una lista de comprensión en lugar de un bucle para mejorar el rendimiento

Tengo un tipo de un diccionario (ejemplo)

l =('1037_97',["a","b","c","d","e"]) 

Deseo guardar un archivo (formato las) pero Liblas puede escribir solo un punto.

 for l in Groups.iteritems(): for p in xrange(len(l[1])): file_out.write(l[1][p]) 

Estoy tratando de usar, si es posible, una Lista de Comprensiones para guardar código y acelerar el ciclo.

Si desea una solución más corta, considere usar map() para el ciclo interno, o incluso para ambos. Pero es poco probable que obtenga un aumento significativo en el rendimiento. Sin embargo, for p in l[1]: aún puede ser más rápido que esa construcción con xrange . El siguiente ejemplo debería hacer lo que quería en una sola línea:

 map(lambda g: map(file_out.write, g), groups.itervalues()) 

Ahora vamos a comparar el rendimiento de diferentes implementaciones. Aquí traté de medir los tiempos en algunos datos de prueba:

 import timeit groups = dict(('1037_%d' % i, ["a","b","c","d","e"]) for i in xrange(100)) class FOut(object): def write(self, v): #print v pass file_out = FOut() def using_map(): map(lambda g: map(file_out.write, g), groups.itervalues()) def initial_version(): for l in groups.iteritems(): for p in xrange(len(l[1])): file_out.write(l[1][p]) def seq_iteration(): for l in groups.iteritems(): for p in l[1]: file_out.write(p) def seq_iteration_values(): for l in groups.itervalues(): for p in l: file_out.write(p) def list_compr(): [[file_out.write(v) for v in g] for g in groups.itervalues()] tests = ('initial_version', 'using_map', 'seq_iteration', 'list_compr', 'seq_iteration_values') for test in tests: print test, timeit.timeit('%s()'%test, 'from __main__ import %s'%test, number=10000) 

Y el resultado es:

 initial_version 0.862531900406 using_map 0.703296899796 seq_iteration 0.541372060776 list_compr 0.632550954819 seq_iteration_values 0.493131160736 

Como puede ver, su versión inicial es la más lenta, la corrección de iteración ayuda mucho, la versión map() es corta, pero no tan rápida como la versión con itervalues() . La comprensión de la lista que crea listas innecesarias no es mala, pero sigue siendo más lenta que el ciclo normal.

Las comprensiones de bucles no necesariamente aceleran un bucle. Solo aceleran un ciclo si el resultado final debería ser una lista. Las comprensiones de listas son más rápidas que crear una lista vacía y agregarla una por una.

En su caso, desea escribir elementos en un archivo y no crear una nueva lista. El coste de creación de la lista se desperdicia.

xrange() embargo, no necesita la llamada xrange() , solo xrange() un bucle sobre l[1] . Tampoco necesita .iteritems() , ya que ignora las claves. Use .itervalues() lugar:

 for lst in Groups.itervalues(): for p in lst: file_out.write(p) 

Utilicé lst como una variable de bucle; l se confunde fácilmente para i en muchas fonts