0

I have a list of strings that may contain digits. I would like to sort this list alphabetically, but every time the String contains a number, I want it to be sorted by value. For example, if the list is

['a1a','b1a','a10a','a5b','a2a'], 

the sorted list should be

['a1a','a2a','a5b','a10a','b1a']

In general I want to treat each number (a sequence of digits) in the string as a special character, which is smaller than any letter and can be compared numerically to other numbers.

Is there any python function which does this compactly?

4
  • How would you compare 'ab1c' and 'a1ef'? Commented Jun 10, 2021 at 9:59
  • assuming numbers are smaller than letters I would compare the character '1' with the letter 'b' and put 'a1ef' before 'ab1c'. In general I want to look at each number in the string as a special character, which is smaller than any letter and can be compared numerically to other numbers. Commented Jun 10, 2021 at 10:03
  • Can't you use mylist.sort() method ? Commented Jun 10, 2021 at 10:10
  • No, sort will put 'a2a' after 'a10a' although 10 is larger than 2. Commented Jun 10, 2021 at 10:16

1 Answer 1

1

You could use the re module to split each string into a tuple of characters and grouping the digits into one single element. Something like r'(\d+)|(.)'. The good news with this regex is that it will return separately the numeric and non numeric groups.

As a simple key, we could use:

def key(x):
    # the tuple comparison will ensure that numbers come before letters
    return [(j, int(i)) if i != '' else (j, i)
        for i, j in re.findall(r'(\d+)|(.)', x)]

Demo:

lst = ['a1a', 'a2a', 'a5b', 'a10a', 'b1a', 'abc']
print(sorted(lst, key=key)

gives:

['a1a', 'a2a', 'a5b', 'a10a', 'abc', 'b1a']

If you want a more efficient processing, we could compile the regex only once in a closure

def build_key():
    rx = re.compile(r'(\d+)|(.)')
    def key(x):
        return [(j, int(i)) if i != '' else (j, i)
            for i, j in rx.findall(x)]
    return key

and use it that way:

sorted(lst, key=build_key())

giving of course the same output.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.