El día 2 de junio de 2011 23:32, Manuel Enrique González Ramírez <maeng...@gmail.com> escribió: > Hola a tod@s, > Tengo la siguiente situación: > Un archivo de 29Mb que contiene 281.351 lineas. El archivo tiene la > siguiente estructura: > 1|2011-05-20 23:08:56|122711527|OPERADOR1|HOST TO HOST|212454|10000|HOST > CLIENTE|192630167 > 2|2011-05-20 23:09:08|122711530|OPERADOR12|HOST TO > HOST|57212454|1000|HOST CLIENTE|192630168 > 3|2011-05-20 23:09:42|122711538|OPERADOR1|HOST TO > HOST|454545454545|2000|HOST CLIENTE|192630169 > 4|2011-05-20 23:10:03|122711544|OPERADOR1|HOST TO > HOST|121221211|20000|HOST CLIENTE|192630170 > 5|2011-05-20 23:10:09|122711547|OPERADOR1|HOST TO HOST > ESPECIAL|4545|5000|HOST CLIENTE|192630171 > 6|2011-05-20 23:10:46|122711554|OPERADOR1|HOST TO HOST > ESPECIAL|545454445|5000|HOST CLIENTE|192630172 > . > . > Del cual debo capturar la última sección, es decir, el número que me > representa una secuencia (192630167, 192630168, etc). > Lo hago así: > fc = open('archivo.txt','r') > for linea in fc: > b = linea.rfind('|') > posi = b + 1 > posf = posi + 9 > secuenciac = linea[posi:posf] > print secuenciac
Supongo que esto es muy lento y que con el split habrás notado una buena mejoría. Pero todavía se puede hacer mejor, rsplit es lo suyo: In [9]: linea = "1|2011-05-20 23:08:56|122711527|OPERADOR1|HOST TO HOST|212454|10000|HOST CLIENTE|192630167" In [10]: timeit linea.split('|')[-1] 1000000 loops, best of 3: 1.2 us per loop In [11]: timeit linea.rsplit('|',1)[-1] 1000000 loops, best of 3: 695 ns per loop In [12]: linea.rsplit('|',1)[-1] Out[12]: '192630167' Para hacer esos mini-benchmarks tan chulos, se puede hacer facilmente con ipython. Para un profiling mejor busca por san google temas de python profiling e incluso python profiling kcachegrind. Lo suyo para optimizar es poder medir en que estas gastando el tiempo ;-) > Esto tarda en promedio 3 minutos (que es demasiado comparado con el tiempo > que tarda [1min en promedio] con el script que me pasaron en Perl). > Ahora, para sumarle al problema del tiempo que tarda dicha proceso, el > resultado del ciclo anterior debe escribirse en otro archivo (datos.csv); > eso lo hago así: > # Abro un archivo para edición > fdif = open('datos.csv','a') > fdif.writelines('"'+secuenciac+'"; \n') > fdif.close() > Y esto eleva exponencialmente el tiempo. :( No alcanzo a entender el uso de writelines: http://docs.python.org/library/stdtypes.html#file.writelines Supongo que no abres y cierras el fichero cada vez, pero tengo que preguntarlo, ¿lo haces? Si lo estás haciendo, un profiler gritaría que ese es el primer punto a optimizar. > Estuve buscando en San Google y en un hilo anterior (así como en e foro de > majibu) obtuve documentación donde se habla de lectura de archivos enormes > con python usando un mínimo de tiempo: > http://effbot.org/zone/wide-finder.htm > > def process(file, chunk): > f = open(file) > f.seek(chunk[0]) > d = defaultdict(int) > for page in pat.findall(f.read(chunk[1])): > d[page] += 1 > return > > Perdón pero no acabo de entender cómo implementar algo que me funcione > utilizando el mínimo de tiempo como dicen que sucede por ejemplo con el > process anterior. > Se que se puede mejorar dichas situaciones pero lo poco que aún se de Python > no me deja ser más eficiente (.. y es que mi ignorancia es infinita) > Alguien me puede colaborar??? > Creo que lo mejor es olvidarse un poco de conseguir la solución más eficiente por ahora. Primero juega con python y cuando tengas soltura irás haciendo el código más óptimo de forma fácil. Por ejemplo, la optimización del rsplit no se me hubiera podido ocurrir sin conocer la existencia del rsplit. Para saber por qué va más rápido hay que pensar en la cantidad de objetos a crear/destruir en una y otra solución, aparte de que una requiere un recorrido mayor de la cadena que la otra. Espero que el correo te haya resultado útil. Un saludo: Javi _______________________________________________ Python-es mailing list Python-es@python.org http://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/