I am trying to sort a list containing strings that are written in a certain format.
Here is an example of said list:
numberList = ['Task #59;', 'Task #40.5; additional', 'Task #40.9; test', 'Task #40; Task Description Difference; test', 'Task #11;', 'Task #12;', 'Task #1;', 'Task #30.1;']
I am currently use this function below that I found online and modified based on an older post.
def natural_sort(listnum):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9] )', key)]
listnum.sort(key=alphanum_key)
return listnum
It works as intended, expect it would always sort Task #40; behind Task #40.5; and Task #40.9;.
['Task #1;', 'Task #11;', 'Task #12;', 'Task #30.1;', 'Task #40.5; additional', 'Task #40.9; test', 'Task #40; Task Description Difference; test', 'Task #59;']
However, if I make it Task #40.0; it would sort correctly.
['Task #1;', 'Task #11;', 'Task #12;', 'Task #30.1;', 'Task #40.0; Task Description Difference; test', 'Task #40.5; additional', 'Task #40.9; test', 'Task #59;']
Is there anyway to sort Task #40; in front of Task #40.5; and Task #40.5; without having to make it Task #40.0?
Here is a link to the post that I got the code form: Is there a built in function for string natural sort?
CodePudding user response:
Use a regex that extracts the number part and converts it to a float to be used as the key
numberList = ['Task #59;', 'Task #40.5; additional', 'Task #40.9; test',
'Task #40; Task Description Difference; test', 'Task #11;', 'Task #12;', 'Task #1;', 'Task #30.1;']
numberList = sorted(numberList, key=lambda v: float(re.search(r"Task #([\d.] );", v).group(1)))
print(numberList)
['Task #1;', 'Task #11;', 'Task #12;', 'Task #30.1;', 'Task #40; Task Description Difference; test', 'Task #40.5; additional', 'Task #40.9; test', 'Task #59;']