2

For example, consider the string '3a+1+4c+3b'. Then, using some regex, you split that into ['3a','1','4c','3b']. How could I rearrange that list so that it is sorted such that the number without a letter following is put first in the list, then the rest of the elements are sorted in the in increasing values of number/letter combinations? For example, ['3a','1','4c','3b'] becomes ['1','3a','3b','4c'].

Edit:

So, just to clarify, I did use sorted, but if I use it, for example, on 2k+1-6j+9i, which turns into ['1', '2k', '6j', '9i'], as you can seem it is not sorted in order of increasing letter value. I want it to instead be ['1','9i','6j','3k'].

R. Kap
  • 599
  • 1
  • 10
  • 33

2 Answers2

1

You can use a key for sorted():

>>> sorted(['3a','5','4c','2b'], key=lambda x: (not x.isdigit(), x[::-1]))
['5', '3a', '2b', '4c']

Note, though, that it might not work how you expect it to if your strings are more than two characters long. You might do something like this:

sorted([...], key=lambda x: (not x.isdigit(), x[-1], int(x[:-1]) if x[:-1] else int(x)))
zondo
  • 19,901
  • 8
  • 44
  • 83
  • What does `(len(x),x[::-1])` actually do in the `lambda` function actually do? – R. Kap Mar 30 '16 at 21:43
  • @R.Kap: I have changed it slightly, but it returns a tuple of whether or not the string is a number and the reverse of the string. If the string is a number, the tuple would be `(0, reversed_string)`, but if it isn't, it is `(1, reversed_string)`. Since tuples with a lower value come first, a string that is just a number will come before a string that is not. Using the reversed string as the second argument puts the last character, the letter, as of more importance than the others. – zondo Mar 30 '16 at 21:53
0

Sort it with a key that returns a tuple containing the first priority - whether the element isn't all digits - followed by the second priority - the letters in the element - followed by the possible third priority - the integer value of the numbers in the element.

def sorter(l):
    return sorted(l, key=lambda x: (not x.isdigit(),
                                    ''.join(filter(str.isalpha, x)),
                                    int(''.join(filter(str.isdigit, x)))))

Results:

>>> sorter(['3a','1','4c','3b'])
['1', '3a', '3b', '4c']
>>> sorter(['1231212', '1a'])
['1231212', '1a']
>>> sorter(['13a', '3a'])
['3a', '13a']
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97