Dos listas, comparación más rápida en Python.

Estoy escribiendo un script en Python (2.7) para comparar dos listas. Estas listas se crean a partir de archivos mediante la lectura de su contenido. Los archivos son solo archivos de texto, no binarios. El archivo 1 solo contiene hashes (sum MD5 de una palabra de texto simple), el archivo 2 es hash: plain. Las listas tienen una longitud diferente (lógicamente, puedo tener menos entradas “resquebrajadas” que los hashes) y ambas no pueden ordenarse porque tengo que conservar el orden, pero este es el siguiente paso de lo que estoy tratando de lograr. Hasta ahora mi código simple se ve así:

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import os def ifexists(fname): if not os.path.isfile(fname): print('[-] %s must exist' % fname) sys.exit(1) if len(sys.argv) < 2: print('[-] please provide CRACKED and HASHES files') sys.exit(1) CRACKED=sys.argv[1] HASHES=sys.argv[2] sk_ifexists(CRACKED) sk_ifexists(HASHES) with open(CRACKED) as cracked, open(HASHES) as hashes: hashdata=hashes.readlines() crackdata=cracked.readlines() for c in crackdata: for z in hashdata: if c.strip().split(':', 1)[0] in z: print('found: ', c.strip().split(':', 1)) 

Básicamente, tengo que reemplazar el hash encontrado en la lista de HASHES por el hash de la línea correspondiente: plano encontrado en la lista CRACKED. Estoy iterando a través de CRACKED ya que cada vez será más corto. Así que mi problema es que el código anterior es muy lento para listas más largas. Por ejemplo, el procesamiento de dos archivos de texto con 60k líneas puede demorar hasta 15 minutos. ¿Cuál sería tu sugerencia para acelerarlo?

Almacene uno de estos archivos en un diccionario o conjunto; eso saca un bucle completo y las búsquedas son O (1) tiempo constante en promedio.

Por ejemplo, parece que el archivo crackdata se puede convertir fácilmente en un diccionario:

 with open(CRACKED) as crackedfile: cracked = dict(map(str.strip, line.split(':')) for line in crackedfile if ':' in line) 

y ahora solo tienes que pasar el otro archivo una vez :

 with open(HASHES) as hashes: for line in hashes: hash = line.strip() if hash in cracked: print('Found:', hash, 'which maps to', cracked[hash])