-2

I'm trying to make a python function in which I give a certain list, and it returns a list with sorted positions of elements (not starting with 0) . For example:

list = [9,3,4,1]
function(list) = [4,2,3,1]

or

list = [2,2,6,5]
function(list) = [1,1,3,2]
Siddharth Satpathy
  • 2,737
  • 4
  • 29
  • 52
T.Gox
  • 1
  • 1
  • 4
    You probably mean the position in a *sorted* list? – Willem Van Onsem Dec 19 '18 at 22:03
  • Make a copy of the list, remove duplicates from it, and sort it. Then loop through the original list and get the index of each element in the sorted copy. – Barmar Dec 19 '18 at 22:04
  • I understand it can sometimes be hard to google when you don't already know the right technical term to search for, so here it is: **argsort**. – wim Dec 19 '18 at 22:06
  • 1
    @PatrickArtner: Note that this introduces the complication of the values in the original `list` not being unique, and wants the duplicates to share a common index. The duplicate's input `list` was unique, so this didn't come up. – ShadowRanger Dec 19 '18 at 22:07
  • @WillemVanOnsem Yes exact the position in a sorted list – T.Gox Dec 19 '18 at 22:12
  • 1
    Why do you want the output for `[2,2,6,5]` to be `[1,1,3,2]`. It should be `[1,1,4,3]` right? Because there are two 2's so they both get assigned rank 1. But they tied for first place, so the next value is in 3rd place, NOT second place. I mean, you can define the problem any way you want to, but it seems very odd to me, personally. Cheers. – Ray Toal Dec 19 '18 at 22:17

1 Answers1

3

Create a dict with key being elements of the list and value being the position. In order to get the unique value convert the list to set first

list1 = [2,2,6,5]
d = {x: i for i, x in enumerate(sorted(set(list1)), start=1)}
[d[k] for k in list1]

Output

[1, 1, 3, 2]
wim
  • 338,267
  • 99
  • 616
  • 750
mad_
  • 8,121
  • 2
  • 25
  • 40
  • The OP provided two inputs; the second of them isn't unique, and this won't work for it. – ShadowRanger Dec 19 '18 at 22:08
  • @ShadowRanger Actually, uniqueness isn't a problem here. off-by-one-error is (the range is both augmented and offset). – wim Dec 19 '18 at 22:09
  • @ShadowRanger was still editing the post. Thanks for the comment though – mad_ Dec 19 '18 at 22:10
  • @mad_: You can simplify a bit by making `d = {x: i for i, x in enumerate(sorted(set(list1)), 1)}`; no need for `zip`, storing a separate `set`, `range`, `len`, etc. calls. `enumerate`+dict comprehension is both faster and cleaner. – ShadowRanger Dec 19 '18 at 22:12
  • Sorting a set is a valid operation? Actually curios now, as I thought it's not something you should do – user8408080 Dec 19 '18 at 22:22
  • 3
    @user8408080 sets themselves can't be sorted in any meaningful way, but `sorted(some_set)` produces a sorted list with all the members of that set. – Adam Smith Dec 19 '18 at 22:23
  • 1
    @user8408080: Expanding on @AdamSmith, `sorted` works on *any* input iterable (generators, strings, etc.), producing a brand new `list` already in sorted order. `sorted`, if implemented in Python, would be exactly equivalent to `def sorted(it, *, key=None, reverse=False): newlist = list(it); newlist.sort(key=key, reverse=reverse); return newlist`; the "takes input, makes new sorted `list` output" design makes it suitable for one-lining many things, e.g. in this case producing a sorted `list` of unique values in `list1` by adding on a conversion to `set` to uniquify before sorting. – ShadowRanger Dec 21 '18 at 19:02
  • Thank you very much for your response, I think it is all clear now – user8408080 Dec 21 '18 at 19:25