Мне нужно найти n самых больших элементов в списке кортежей. Вот пример для 3 верхних элементов.
# I have a list of tuples of the form (category-1, category-2, value)
# For each category-1, ***values are already sorted descending by default***
# The list can potentially be approximately a million elements long.
lot = [('a', 'x1', 10), ('a', 'x2', 9), ('a', 'x3', 9),
('a', 'x4', 8), ('a', 'x5', 8), ('a', 'x6', 7),
('b', 'x1', 10), ('b', 'x2', 9), ('b', 'x3', 8),
('b', 'x4', 7), ('b', 'x5', 6), ('b', 'x6', 5)]
# This is what I need.
# A list of tuple with top-3 largest values for each category-1
ans = [('a', 'x1', 10), ('a', 'x2', 9), ('a', 'x3', 9),
('a', 'x4', 8), ('a', 'x5', 8),
('b', 'x1', 10), ('b', 'x2', 9), ('b', 'x3', 8)]
Я пытался использовать heapq.nlargest
. Однако он возвращает только первые 3 самых больших элемента и не возвращает дубликаты. Например,
heapq.nlargest(3, [10, 10, 10, 9, 8, 8, 7, 6])
# returns
[10, 10, 10]
# I need
[10, 10, 10, 9, 8, 8]
Я могу думать только о приближении грубой силы. Это то, что у меня есть, и это работает.
res, prev_t, count = [lot[0]], lot[0], 1
for t in lot[1:]:
if t[0] == prev_t[0]:
count = count + 1 if t[2] != prev_t[2] else count
if count <= 3:
res.append(t)
else:
count = 1
res.append(t)
prev_t = t
print res
Любые другие идеи о том, как я могу это реализовать? Спасибо!
РЕДАКТИРОВАТЬ: timeit
результаты для списка из 1 миллиона элементов показывают, что решение mhyfritz работает в 1/3 времени грубой силы. Не хотел делать вопрос слишком длинным. Так что добавили больше подробностей в мой ответ .