Savannah
Savannah

Reputation: 45

Ranking list in ascending order but keeping the index same

I have a list of numbers, that I want to rank in ascending order, but their index is important, I want to keep them unchanged.

for example:

index 0  1 2 3  4  5  6 7 8  9

a =  [22,2,4,53,43,32,3,5,1,101] 

to:

index  8 1 6 2 7  0  5 4  3   9
a =   [1,2,3,4,5,22,32,43,53,101] 

how to arrange them like that?

Thanks

Upvotes: 1

Views: 529

Answers (3)

atanay
atanay

Reputation: 174

By definition, the index of an element in a list is it's location in the list. If you want to keep the original indexes as information, you can change the elements of the list to be tuples/lists of length 2, with first element as the value, and the index as the second element.

a = [1,2,3,4,5,22,32,43,53,101]

# adding original index to each element
for i in range(len(a)):
    a[i] = (a[i],i)

# sorting the list based on the first number in each element
def compare(x):
    return -x[0]
a.sort(key=compare)

print(a)

EDIT: as suggested by the comments and other answer, you can replace some of the code using built-in functions and more compact syntax:

  • you can enumerate constructor to, well, enumerate the list and then make a list from the object using the list constructor
  • you can replace the compare function with a compact lambda. like lambda x : x[1] while I would usually make these changes when I code, I tried to make the code as simple as I can to understand, in case you are not familiar with some of the functions described above.

Upvotes: 1

Olvin Roght
Olvin Roght

Reputation: 7812

Basically, my answer is an addition to Alex's (which posted 2 minutes after I left this comment).

There's built-in enumerate() function which yields tuple of index and value of each item in iterable, you may pass it's result directly into sorted() with itemgetter(1) as key argument. It will return list of tuples (index, value) sorted by second element (which is value).

To get two separate lists from list of pairs, you can unpack list into zip() and assign result to two separate variables.

Code:

from operator import itemgetter

a = [1,2,3,4,5,22,32,43,53,101]
indexes, values = zip(*sorted(enumerate(a), key=itemgetter(1)))

Upvotes: 2

Alex
Alex

Reputation: 7075

You can recreate the list as a list of tuples that are (index, value):

>>> arr = list(enumerate(a))
>>> arr
[(0, 22),
 (1, 2),
 (2, 4),
 (3, 53),
 (4, 43),
 (5, 32),
 (6, 3),
 (7, 5),
 (8, 1),
 (9, 101)]

You can then sort this either by the original index or the value using 0 for index and 1 for value:

>>> sorted(arr, key=lambda x: x[1])
[(8, 1),
 (1, 2),
 (6, 3),
 (2, 4),
 (7, 5),
 (0, 22),
 (5, 32),
 (4, 43),
 (3, 53),
 (9, 101)]

Or using itemgetter, as suggested by @Olvin Roght

>>> from operator import itemgetter
>>> sorted(arr, key=itemgetter(1))

Upvotes: 1

Related Questions