How to sort a list of strings containing letters and numbers

Question:

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?

Asked By: Kenny

||

Answers:

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;']
Answered By: azro
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.