Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort list to make letters come before digits in any position

Say I have the following list:

l = ['erget', 'a1', 'm1', 'aa', 'ae', 'mea', 'erge4', 'erge7', 'm2', 'me2', 'mei']

When using sorted() over lists of strings that also contain digits, the digits come before the letters, so in this case it would yield:

sorted(l)
['a1', 'aa', 'ae', 'erge4', 'erge7', 'erget', 'm1', 'm2', 'me2', 'mea', 'mei']

I've seen some answers like this one on how to make letters appear before digits, but only for a single digit or letter. Is it possible to also do it using some key in sorted() when the digit can be anywhere in the string? So expected output:

['aa', 'ae', 'a1', 'erget', 'erge4', 'erge7', 'mea', 'mei', 'me2', 'm1', 'm2']
like image 282
yatu Avatar asked Jan 27 '23 01:01

yatu


2 Answers

You can use sorted with a list of tuples as a custom key:

L = ['erget', 'a1', 'm1', 'aa', 'ae', 'mea', 'erge4', 'erge7', 'm2', 'me2', 'mei']
res = sorted(L, key=lambda x: [(i.isdigit(), i) for i in x])

# ['aa', 'ae', 'a1', 'erget', 'erge4', 'erge7', 'mea', 'mei', 'me2', 'm1', 'm2']
like image 100
jpp Avatar answered Mar 02 '23 22:03

jpp


You can use a key function that iterates through each character of a given string and prepends 'z' to those that are digits so that they are sorted after alphabets:

l = ['erget', 'a1', 'm1', 'aa', 'ae', 'mea', 'erge4', 'erge7', 'm2', 'me2', 'mei']
sorted(l, key=lambda s: ['z' + c if c.isdigit() else c for c in s])

This returns:

['aa', 'ae', 'a1', 'erget', 'erge4', 'erge7', 'mea', 'mei', 'me2', 'm1', 'm2']
like image 44
blhsing Avatar answered Mar 02 '23 21:03

blhsing