Python Forum
How to sort a list with duplicates and return their unique indices.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to sort a list with duplicates and return their unique indices.
#1
Given a list:

lst = [48,52,35,35,44,35]
I want to sort the list in descending order, so I use this:


sortedlst = sorted(slst, reverse = True)
I also want the original index in a sorted position as well. Like this:

sortedlstindx = [1,0,4,2,3,5]
for that I use this code:

sortedindx = [elem.index(lst) for elem in sorted(lst, reverse = True)]
The result I got is this:

sortedindx = [1,0,4,2,2,2]
How can I modify the code to give the result I want?
It's a shame I cannot use dict or set to help with this problem. No libraries import either sadly.
perfringo write Sep-21-2022, 10:08 AM:
Nobody expects the Spanish Inquisition! Our chief weapon is surprise! Surprise and fear. Fear and surprise. Let me tell you something: when you're looking at your thread tonight and manic silence meets you don't come cryin' to me. Instead do use respective tags while posting code, output and errors (refer to BBCode help). This empowers others to help you. And... Always Look on the Bright Side of Life: I added them this time but if in the future you do it all by yourself I feel happy.
Reply
#2
You could use built-in enumerate function to capture indices:

>>> print(*enumerate(lst))
(0, 48) (1, 52) (2, 35) (3, 35) (4, 44) (5, 35)
You can provide key function to sorted so that it sorts values, not indices:

>>> print(sorted(enumerate(lst), key=lambda i: i[1], reverse=True))
[(1, 52), (0, 48), (4, 44), (2, 35), (3, 35), (5, 35)]
Then you can use built-in zip for row-to-columns:

>>> print(*zip(*sorted(enumerate(lst), key=lambda i: i[1], reverse=True)))
(1, 0, 4, 2, 3, 5) (52, 48, 44, 35, 35, 35)
You can unpack it right away:

>>> indices, values = zip(*sorted(enumerate(lst), key=lambda i: i[1], reverse=True))
>>> indices
(1, 0, 4, 2, 3, 5)
>>> values
(52, 48, 44, 35, 35, 35)
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
He wanted unique elements.

lst = [48,52,35,35,44,35]


def unique_sort_index(sequence, reverse=False):
    unique = sorted(set(sequence), reverse=reverse)
    for element in unique:
        yield sequence.index(element)


def unique_sort_index2(sequence, reverse=False):
    seen = set()
    for index, element in sorted(enumerate(sequence), key=lambda x: x[1]):
        if element not in seen:
            seen.add(element)
            yield index


print("unique_sort_index")
for idx in unique_sort_index(lst):
    print(idx, lst[idx])

print("\nunique_sort_index2")
for idx in unique_sort_index2(lst):
    print(idx, lst[idx])
Output:
unique_sort_index 2 35 4 44 0 48 1 52 unique_sort_index2 2 35 4 44 0 48 1 52
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
I think DeaD_EyE is not interpreting the question correctly. I do not think "unique" means that the lst should be pared down to only contain unique values. I think the problem is the way the index sort was done returned non-unique values. The problem is caused by using "index" which returns the first match, not the index of the element.

To solve the problem, create a list of index values, and sort these using a key that references the original list. This is what perfingo did with the index, value tuples. Another way to do the same thing is create a separate list of index values and sort the index list using a key that references the original list.
lst = [48,52,35,35,44,35]
index = range(len(lst))
sorted_index = sorted(index, key=lambda i: lst[i])
print(sorted_index)
I like perfingo's method because it produces the sorted list and the sorted index list at the same time. I would use that if I needed both results. If I only needed the sorted index list I might use the separate array.

You could also do this with numpy's argsort()
import numpy as np

lst = np.array([48,52,35,35,44,35])
print(lst.argsort())
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  help with adding duplicates elements together in a list 2ECC3O 5 1,157 Sep-10-2022, 07:11 AM
Last Post: 2ECC3O
  sorting a list using unicodes acending order, no loops, no sort(), using recursion lrn2codee 14 4,387 Jun-23-2021, 07:33 PM
Last Post: deanhystad
  how to sort a list without .sort() function letmecode 3 2,502 Dec-28-2020, 11:21 PM
Last Post: perfringo
  Get 5 most unique combinations of elements in a 2D list wanttolearn 1 1,747 Sep-24-2020, 02:26 PM
Last Post: buran
  Return the sum of the first n numbers in the list. pav1983 3 1,973 Jun-24-2020, 03:37 AM
Last Post: deanhystad
  How can I print the number of unique elements in a list? AnOddGirl 5 2,392 Mar-24-2020, 05:47 AM
Last Post: AnOddGirl
  duplicates nsx200 3 1,763 Nov-12-2019, 08:55 AM
Last Post: nsx200
  Exercise list remove duplicates RavCOder 9 4,106 Oct-23-2019, 04:16 PM
Last Post: jefsummers
  list and sort query arian29 2 1,654 Sep-18-2019, 06:19 PM
Last Post: ndc85430
  [split] Manual Sort without Sort function fulir16 2 2,532 Jun-02-2019, 06:13 AM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020