Использовать отсортировано + перечислять :
L = [8, 1, 4, 2]
positions = {e: i for i, e in enumerate(sorted(L), 1)}
result = [positions[e] for e in L]
print(result)
Вывод
[4, 1, 3, 2]
Этот подход O(n log n)
так как сортирует массив. Если L
имеет дублирующиеся значения, вы можете сделать следующее:
from collections import defaultdict, deque
L = [8, 1, 4, 8, 2]
positions = defaultdict(deque)
for i, e in enumerate(sorted(L), 1):
positions[e].append(i)
result = [positions[e].popleft() for e in L]
print(result)
Вывод
[4, 1, 3, 5, 2]
Причина использования deque для обеспечения стабильности ордера, первые 8 занимают первую позицию, сохраняя при этом операцию popleft O(1)
, поэтому алгоритм остается O(n log n)
.