В python используйте функцию nsmallest в модуле heapq - она предназначена именно для такого рода задач.
Пример (проверено) для Python 2.5 и 2.6:
import heapq, glob
def my_iterable():
for fname in glob.glob("in_s*.txt"):
f = open(fname, "r")
for line in f:
items = line.split()
yield fname, items[0], float(items[6])
f.close()
result = heapq.nsmallest(10, my_iterable(), lambda x: x[2])
print result
Обновление после вышеуказанного ответа принято
Глядя на исходный код для Python 2.6, кажется, что есть вероятность, что он сделает list(iterable)
и сработает над этим ... если это так, то это не сработает с тысячами файлов с миллионами строк в каждом. Если первый ответ дает вам MemoryError и т. Д., Вот альтернатива, которая ограничивает размер списка до n (n == 10 в вашем случае).
Примечание: только 2,6; если вам это нужно для 2.5, используйте условное heapreplace()
, как описано в документации. Использует heappush()
и heappushpop()
, которые не имеют key
arg :-(, поэтому мы должны подделать его.
import glob
from heapq import heappush, heappushpop
from pprint import pprint as pp
def my_iterable():
for fname in glob.glob("in_s*.txt"):
f = open(fname, "r")
for line in f:
items = line.split()
yield -float(items[6]), fname, items[0]
f.close()
def homegrown_nlargest(n, iterable):
"""Ensures heap never has more than n entries"""
heap = []
for item in iterable:
if len(heap) < n:
heappush(heap, item)
else:
heappushpop(heap, item)
return heap
result = homegrown_nlargest(10, my_iterable())
result = sorted(result, reverse=True)
result = [(fname, fld0, -negfld6) for negfld6, fname, fld0 in result]
pp(result)