This is a fun little challenge that confronted me recently. I\'ll provide my answer below, but I\'m curious to see whether there are more elegant or efficient solutions.
Here's one that works for the bonus test too:
def mykey(s):
lst = re.findall(r'(\d+)|(\D+)', s)
return [(0,a.lower()) if a else (1,int(n)) for n, a in lst]\
+ [a for n, a in lst if a]\
+ [len(n) for n, a in lst if n]
def mysort(lst):
return sorted(lst, key=mykey)
With this type of pattern, re.findall breaks the string to a list of tuples, e.g.
>>> re.findall(r'(\d+)|(\D+)', 'ab12cd')
[('', 'ab'), ('12', ''), ('', 'cd')]