[Python-es] Buscar, leer y escribir archivos grandes con Python
Alexis Roda
alexis.roda.villalonga en gmail.com
Vie Jun 3 21:19:57 CEST 2011
En/na Kiko ha escrit:
En el programa que mandaste en el primer mensaje parece implícito que la
longitud del código es siempre de 9 caracteres. Esto hace innecesario el
uso de rsplit o rfind.
def procesa(entrada, salida) :
with open(entrada,'r') as input:
with open(salida,'w') as output:
for l in input :
output.write(l[-9:])
In [1]: l = "1|2011-05-20 23:08:56|122711527|OPERADOR1|HOST
TOHOST|212454|10000|HOST CLIENTE|192630167"
In [2]: timeit l.rsplit("|", 1)[-1]
1000000 loops, best of 3: 827 ns per loop
In [3]: timeit l[l.rindex("|")+1:]
1000000 loops, best of 3: 676 ns per loop
In [4]: timeit l[l.rfind("|")+1:]
1000000 loops, best of 3: 682 ns per loop
In [5]: timeit l[-9:]
1000000 loops, best of 3: 208 ns per loop
Fíjate en que utilizar rfind (o rindex) como hacías originalmente es mas
eficiente que utilizar rsplit. La explicación es que rsplit crea dos
cadenas (la "mitad" izquierda y la derecha), una lista con las dos
cadenas y finalmente accede al último elemento de la lista. En la
versión con rindex se crea directamente la cadena derecha.
Como curiosidad, en el caso de utilizar un método de l podrías arañar
unos nanosegundos haciendo algo como:
In [6]: rf=l.rfind
In [7]: timeit l[rf("|")+1:]
1000000 loops, best of 3: 602 ns per loop
con esto evitas que el interprete tenga que buscar el método rfind de l
en cada iteración.
> Claramente, rsplit parece que funciona mejor. He hecho mi función
> (abrekiko) con una list comprehesion y también va un poquito más lenta
> que con el for a pelo y tenía entendido que usar list comprehensions era
> más efectivo.
Las list comprehension sirven para crear listas. Lo que hace tu código
es equivalente a:
def abrelasi(entrada,salida):
lista = []
with open(entrada,'r') as input:
with open(salida,'w') as output:
for l in input :
lista.append(output.write(l.rsplit(',',1)[-1]))
Al final "lista" contiene 300000 valores None. No le veo el sentido.
> ¿Alguien tiene formas más rápidas de lectura de ficheros de texto?
Yo hubiese utilizado cut -d\| -f9 entrada.txt > salida.txt
Como ya te han dicho debes considerar el tiempo de desarrollo mas el
tiempo de ejecución y valorar si el esfuerzo extra vale la pena. Dicho
esto, si quieres aprender, te recomendaría probar el módulo cProfile:
http://docs.python.org/library/profile.html#module-cProfile
este modulo mide el tiempo de ejecución del programa y te ayudará a
descubrir donde está el cuello de botella. Tal vez estés dedicando horas
a optimizar algo que luego no tiene un impacto decisivo en el tiempo
total de ejecución.
En el caso de procesar el archivo tengo la impresión de que el problema
estará en la E/S y no el el procesamiento de los datos en si (utilizando
un programa razonable).
Saludos
Más información sobre la lista de distribución Python-es