2

I've been trying to sort a top-5 leaderboard which includes the score and the username of the account that got the score. Here is my current code:

g = open("scores.txt", "r")
score1 = g.readline().strip()
score2 = g.readline().strip()
score3 = g.readline().strip()
score4 = g.readline().strip()
score5 = g.readline().strip()
print(score1,score2,score3,score4,score5)
print(sorted([score1,score2,score3,score4,score5], reverse = True))
g.close()

It seems to work, but it only sorts the leftmost digits of the scores, for example it sorts 100coolguy 50otherguy 10coolguy 2000coolguy 2otherguy as 50otherguy 2otherguy 2000coolguy 10coolguy 100coolguy.

A list of the scores, and how they should be formatted afterwards:

100otherexample 50example 10otherexample 2000example 2example
2000example 100otherexample 50example 10otherexample 2example
coolguy11
  • 23
  • 3
  • 1
    Hi and welcome to StackOverflow! Can you include the minimal code and dependencies to reproduce the problem? In this case, that would be a list of the names and scores (without the IO) and how they should be formatted afterwards. – erip Sep 22 '21 at 11:11
  • share `"scores.txt"` and the expected result. Share the code that write to the file as well. – balderman Sep 22 '21 at 11:15
  • Does this answer your question? [How to correctly sort a string with a number inside?](https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside) – Stef Sep 22 '21 at 13:38

3 Answers3

1
from natsort import natsorted
print(natsorted([score1,score2,score3,score4,score5], reverse = True))
Eumel
  • 1,298
  • 1
  • 9
  • 19
1

You can first find digits then sort base digits like below:

st = ['100coolguy' , '50otherguy' , '10coolguy' , '2000coolguy' ,'2otherguy']

def find_int(text):
    return int(''.join(t for t in text if t.isdigit()))


st.sort(key=find_int, reverse=True)
print(st)

Output:

['2000coolguy', '100coolguy', '50otherguy', '10coolguy', '2otherguy']
I'mahdi
  • 23,382
  • 5
  • 22
  • 30
  • This would given wrong results if there are other digits later in the strings; for instance `'50coolguy12'` would be sorted as if they had a score of 5012. Instead, you can use `itertools.takewhile`: `int(''.join(itertools.takewhile(str.isdigit, text)))` – Stef Sep 22 '21 at 13:29
0

You need give a custom key to sorted key is what is evaluated instead of the whole list item in the sorting process:

A regex implementation:

import re

l = ["100coolguy", "50otherguy", "10coolguy", "2000coolguy", "2otherguy"]

def my_key(item):
    item_split = re.split("[a-z]", item, 1, flags=re.I)
    return int(item_split[0])

l_sorted = [sorted(l, key=my_key, reverse=True)]
print(l_sorted)

Splits at any character ("[a-z]") for 1 time and ignores case with re.I.

https://docs.python.org/3/howto/sorting.html#key-functions

Tzane
  • 2,752
  • 1
  • 10
  • 21