2014-08-28 25 views
5

Mam tablicę liczb n, na przykład [1,4,6,2,3]. Posortowana tablica jest [1,2,3,4,6], a indeksy tych liczb w starej tablicy to 0, 3, 4, 1 i 2. Jaki jest najlepszy sposób, biorąc pod uwagę tablicę n liczb, aby znaleźć tablicę indeksów?Posortuj listę, a następnie podaj indeksy elementów w oryginalnej kolejności.

Mój pomysł to uruchomienie statystyk zamówień dla każdego elementu. Jednak ponieważ muszę wielokrotnie przepisywać tę funkcję (w konkursie), zastanawiam się, czy jest na to krótka droga.

+1

można pokazać próbę już wykonane? – whereswalden

Odpowiedz

11
>>> a = [1,4,6,2,3] 
>>> [b[0] for b in sorted(enumerate(a),key=lambda i:i[1])] 
[0, 3, 4, 1, 2] 

Objaśnienie:

enumerate(a) zwraca wyliczanie nad krotek składających się z indeksów i wartości w oryginalnej listy: [(0, 1), (1, 4), (2, 6), (3, 2), (4, 3)]

Następnie sorted z key z lambda i:i[1] rodzaju opartych na oryginalnych wartościach (pozycja 1 z każdej krotki).

Wreszcie, zrozumienie listy [b[0] for b in ... ] zwraca oryginalne indeksy (pozycja 0 każdej krotki).

+0

Spowoduje to utworzenie listy wyliczeniowej, posortowanie jej na podstawie oryginalnego klucza, a następnie zwrócenie powiązanego indeksu. Bardzo wydajne rozwiązanie z/dotyczy prędkości i długości kodu. –

+0

Dlaczego dziękuję. Prawdopodobnie powinienem był to skomentować, dzięki temu, zrozumienie list może być nieco trudne do strawienia. – user2085282

+0

Idealnie! Dzięki! – neutralino

1

Oto kolejny sposób:

>>> sorted(xrange(len(a)), key=lambda ix: a[ix]) 
[0, 3, 4, 1, 2] 

Takie podejście nie sortuje pierwotną listę, ale jej indeksy (utworzony z xrange), używając oryginalnej listy jako klucze sortowania.

+0

Jeśli mimo to generujesz pełną listę indeksów, aby to posortować, po co używać 'xrange' zamiast' range'? –

+0

@MarkReed: Wierzę, że 'posortowane' zużyje' xrange' jeden element na raz. Oznacza to, że zostanie wygenerowana tylko jedna lista (posortowana wersja); lista nieposortowanych indeksów nie będzie generowana i przechowywana w przedsprzedaży. – BrenBarn

1

Używanie numpy tablic zamiast list może być korzystne, jeśli wykonujesz wiele statystyk danych. Jeśli zdecydujesz się to zrobić, to będzie działać:

import numpy as np 
a = np.array([1,4,6,2,3]) 
b = np.argsort(a) 

argsort() może działać na listach, jak również, ale wierzę, że w tym przypadku po prostu kopiuje dane do tablicy pierwszy.

0

To powinno załatwić sprawę:

from operator import itemgetter 
indices = zip(*sorted(enumerate(my_list), key=itemgetter(1)))[0] 
Powiązane problemy