Мне нужно получить меньшее n номеров списка в Python. Мне нужно, чтобы это было действительно быстро, потому что это критически важно для производительности, и его нужно повторять много раз.
n обычно не больше 10, а список обычно содержит около 20000 элементов. Список всегда отличается каждый раз, когда я вызываю функцию. Сортировка не может быть выполнена на месте.
Изначально я написал эту функцию:
def mins(items, n):
mins = [float('inf')]*n
for item in items:
for i, min in enumerate(mins):
if item < min:
mins.insert(i, item)
mins.pop()
break
return mins
Но эта функция не может разбить простую сортировку (items) [: n], которая сортирует весь список. Вот мой тест:
from random import randint, random
import time
test_data = [randint(10, 50) + random() for i in range(20000)]
init = time.time()
mins = mins(test_data, 8)
print 'mins(items, n):', time.time() - init
init = time.time()
mins = sorted(test_data)[:8]
print 'sorted(items)[:n]:', time.time() - init
Результаты:
mins(items, n): 0.0632939338684
sorted(items)[:n]: 0.0231449604034
sorted () [: n] работает в три раза быстрее. Я считаю, что это потому, что:
- Операция insert () является дорогостоящей, поскольку списки Python не являются связанными списками.
- sorted () - оптимизированная функция c, а моя - чистый python.
Есть ли способ побить sorted () [: n]?
Должен ли я использовать расширение C, или Pyrex, или Psyco, или что-то подобное?
Заранее спасибо за ваши ответы.