Search code examples
pythonlistsortinglambda

Sorting a list of strings based on string content


I am trying to solve this sorting problem of a list of strings.

All strings begin with an alphanumeric identifier and after the alphanumeric identifier the string will consist of either words or integers.

The output list needs to be organised following these rules:

  • the strings with words must be at the beginning of the list
  • The strings with words are ordered lexicographically, ignoring the identifier
  • the strings with integers must be left in the original order
  • the identifiers must be part of the output strings

example

list = ['a1 9 2 3 1', 'g1 act car', 'zo4 4 7', 'ab1 off key dog', 'a8 act zoo']

reordered_list = [ 'g1 act car', 'a8 act zoo', 'ab1 off key dog', 'a1 9 2 3 1', 'zo4 4 7']

I'm trying to split the strings use the lambda function to sort by the 2nd value but the output is None

list.sort(key = lambda x: x.split()[1])


Solution

  • You can use the sorted function with a key function that returns a tuple of 1 or 2 items based on whether the last character is a digit (since presumably it represents whether it's a string with integers), and prioritize strings with words over strings with integers by giving the first item of the tuple for a string with words a smaller number:

    sorted(l, key=lambda s: (1,) if s[-1].isdigit() else (0, s.split(' ', 1)[1]))
    

    This returns:

    ['g1 act car', 'a8 act zoo', 'ab1 off key dog', 'a1 9 2 3 1', 'zo4 4 7']