Is there a simple way to do a "Filing cabinet" sort of strings containing both alpha and numeric characters?
I.e. a list such as:
[aa2, ab2, bb1, bc1, ab3, aa3, ba2, ba1, aa1, ac1, bb2, bb3, ab1]
is sorted to
[aa1, aa2, aa3, ab1, ab2, ab3, ac1, ba1, ba2, bb1, bb2, bb3, bc1]
I have an idea for a script that dissects them into individual characters, sorts each set, and then reassembles them, but that seems like the hard way. :-)
Here si the final code that works well. Thanks pepr from Experts Exchange D0t k0m and to jamylak for answering before the questions was killed. The built in sorts cannot handle the numerical portion of the sort. I.e. they sort the numerical as lexical...
[aa1, aa11, aa111, aa2, aa3, ba1, ba11, ba2]
... instead of ...
[aa1, aa2, aa3, aa11, aa111, ba1, ba2, ba11]
So this variation of jamylak's code works beautifully ...
def lexinumericalsort(_list):
def _key(item):
# pattern will split strings and letters up to 8 times (intended for device file names)
pattern = ('([a-zA-Z]{0,})(\d{0,})') * 8
try:
result = re.match(pattern, item).groups()
result = list(result)
for no, val in enumerate(result):
if val is '':
result.pop(no) # Remove blanks
try:
# Convert to integer if possible
result[no] = int(result[no])
except ValueError, e:
pass #silence if fails (leaves as character)
return result
except AttributeError, e:
e = ("functions.lexinumericalsort:\n" +
"Unable to resolve list into pattern matched groups.\n" +
str(e))
print e
return None
return sorted(_list, key = _key)