1

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?

SixMore
  • 13
  • 2
  • If they're all of that format, the easiest thing is going to be to just clear the `;` out before comparing. You don't have to modify the actual strings, just use `sort` with a comparison lambda that ignores the last position. – Edward Peters Nov 22 '22 at 21:44

1 Answers1

2

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;']
azro
  • 53,056
  • 7
  • 34
  • 70