usted quiere construir un índice en memoria para el archivo:
- crear una lista vacía
open
el archivo
- leer línea por línea (usando
f.readline()
, y almacenar en la lista una tupla que consiste en el valor sobre el que desea ordenar (extraído con line.split('\t').strip()
) y el desplazamiento de la línea en el archivo (que puede obtener llamando al f.tell()
antes de llamar al f.readline()
)
close
el archivo
sort
la lista
continuación para imprimir el archivo ordenado, vuelva a abrir el archivo y para cada elemento de la lista, utilice f.seek(offset)
para mover el puntero del archivo al principio de la línea, f.readline()
para leer la línea y print
la línea.
Optimización: es posible que desee almacenar la longitud de la línea en la lista, para que pueda usar f.read(length)
en la fase de impresión.
Código de la muestra (optimizado para facilitar la lectura, no la velocidad):
def build_index(filename, sort_col):
index = []
f = open(filename)
while True:
offset = f.tell()
line = f.readline()
if not line:
break
length = len(line)
col = line.split('\t')[sort_col].strip()
index.append((col, offset, length))
f.close()
index.sort()
return index
def print_sorted(filename, col_sort):
index = build_index(filename, col_sort)
f = open(filename)
for col, offset, length in index:
f.seek(offset)
print f.read(length).rstrip('\n')
if __name__ == '__main__':
filename = 'somefile.txt'
sort_col = 2
print_sorted(filename, sort_col)
el comando de ordenamiento unix es una herramienta muy poderosa. Puede controlar el formato del campo para ordenar (numérico, fecha, etc.) y la cantidad de memoria que el programa puede asignar, realizando una división + combinación si es necesario. –
alex ¿Puedes dar un ejemplo? El programa de clasificación en sí mismo lleva bastante tiempo ... del orden de 40 minutos. Esto puede tener algo que ver con la asignación de memoria o el disco IO. No estoy seguro de cómo saber cuál es el cuello de botella, pero supongo que su sugerencia puede ser útil. – fodon
un error en la solución anterior: para usar solo el segundo campo, uno necesita -k 2,2 ... por lo que no está indexado en cero (al menos no en la versión de Kubuntu 11.04). – fodon