0

I have a list of items that I need to sort according to a given score I give it. The code looks something like this:

original_list = [item_1, item_2, item_3]
# ... Here I score the list in a separate function to get a score for each item ...
scored_list = [[35, item_1], [45, item_2], [1, item_3]]
scored_list.sort()
sorted_list = [item[1] for item in scored_list]

So I have a list of items, score each item, sort the list according to the score, and then remove the score variable to keep only the items.

Is this the most efficient way of doing this kind of operation, or are there simpler ways to obtain the same result?

Eli
  • 156
  • 8
  • https://stackoverflow.com/questions/13188476/get-the-nth-element-from-the-inner-list-of-a-list-of-lists-in-python has some pointers to this answer – Paul Brennan Jan 04 '21 at 10:39
  • 1
    Does this answer your question? [Sorting list based on values from another list](https://stackoverflow.com/questions/6618515/sorting-list-based-on-values-from-another-list) – Tomerikoo Jan 04 '21 at 10:40

4 Answers4

1

Efficiency-wise I doubt you can do better. If you are concerned with the number of lines, you can move the sort to inside the comprehension:

scored_list = [[35, item_1], [45, item_2], [1, item_3]]
sorted_list = [item[1] for item in sorted(scored_list)]

But in terms of speed you'll likely not notice a difference. In fact this may be a bit slower than your approach because in-place sort() might be a bit faster as it does not need to make a copy but depending on your data that is negligible.

So I'd say your approach is perfectly fine. If you want to make it more concise, you can use sorted().

Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239
  • 1
    Thank you Bram, I am more for readability than minimizing number of lines at the moment so if it is the same I will keep my original code with comments. Thank you though for the answer. – Eli Jan 04 '21 at 11:38
1

That's the right way, but you can use list comprehensions:

scored_list = [i[1] for i in sorted(scored_list, key=lambda s: s[0])]
AlanWik
  • 326
  • 1
  • 10
0

For disentangling the scores and the items, you can use the:

the_scores, the_items = zip(*scored_list)

For efficiency, there are not much that you can do. Actually, I think that there is not something else that you can do.

Bram Vanroy
  • 27,032
  • 24
  • 137
  • 239
Xxxo
  • 1,784
  • 1
  • 15
  • 24
  • Do you have any proof that that is faster than extracting the second item only with a list comprehension? It might, but I am doubtful. – Bram Vanroy Jan 04 '21 at 10:38
  • This answer is about the "simpler" part. I do not have considered if it is faster or not. – Xxxo Jan 04 '21 at 10:40
0

You could use the key parameter in the sorted() function when you sort the array. You can pass in a lambda function that returns a list of scores using your scoring function as the key.

    def calcScore(x):
       # Calculate score here
       pass
    original_list = [item_1, item_2, item_3].
    sorted_list = sorted(original_list, key=lambda x: [calcScore(x) for x in original_list])