Potrzebuję uzyskać mniejsze liczby n listy w Pythonie. Potrzebuję tego, aby był naprawdę szybki, ponieważ ma kluczowe znaczenie dla wydajności i musi być powtarzany wiele razy.Uzyskiwanie mniejszych n elementów listy w Pythonie
n zwykle nie jest większe niż 10, a lista zwykle zawiera około 20000 elementów. Lista jest zawsze inna za każdym razem, gdy wzywam funkcję. Sortowania nie można wprowadzić w życie.
Początkowo Pisałem tę funkcję:
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
Ale ta funkcja nie może pokonać proste posortowane (przedmioty) [n], która uszeregować całą listę. Oto my Test:
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
Wyniki:
mins(items, n): 0.0632939338684
sorted(items)[:n]: 0.0231449604034
klasyfikowane() [n] jest trzy razy większa. Wierzę, że dzieje się tak dlatego:
- Operacja insert() jest kosztowna, ponieważ listy w Pythonie nie są listami połączonymi.
- posortowane() to zoptymalizowana funkcja c, a moja to czysty pyton.
Czy istnieje sposób na pokonanie posortowane() [: n]? Czy powinienem używać rozszerzenia C, Pyrex lub Psyco, czy coś w tym stylu?
Z góry dziękuję za odpowiedzi.
To jest super szybko! –
Kupa będzie lepsza; nie ma potrzeby pełnego sortowania całej listy dla każdej wstawki, tylko tańsza reheap. – erickson
@erickson: Właśnie edytowane, aby dodać, że bisect.insort może mieć ten sam efekt. –