How to sort a list with duplicates and return their unique indices. - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Homework (https://python-forum.io/forum-9.html) +--- Thread: How to sort a list with duplicates and return their unique indices. (/thread-38243.html) |
How to sort a list with duplicates and return their unique indices. - Echoroom - Sep-21-2022 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. RE: How to sort a list with duplicates and return their unique indices. - perfringo - Sep-21-2022 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) RE: How to sort a list with duplicates and return their unique indices. - DeaD_EyE - Sep-22-2022 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])
RE: How to sort a list with duplicates and return their unique indices. - deanhystad - Sep-23-2022 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()) |