0

It it possible to alphabetize the characters in a string, disregarding upper and lower case? I need them to stay in the case they are in, so I can't use .lower() or .upper(), but I'd like for them to be arranged with the letter taking precedence, so the resulting string would be something like:

"LMmqRRs"

instead of

"LMRRmqs"

Oleh Prypin
  • 33,184
  • 10
  • 89
  • 99
spikey273
  • 23
  • 3
  • This may help: http://stackoverflow.com/questions/10269701/case-insensitive-list-sorting-without-lowercasing-the-result – RKumsher Nov 02 '12 at 18:13
  • 1
    Do you want the sort to be stable (i.e. "aA" would stay "aA" and "Aa" would stay "Aa") or do you want the cases to have a specific order, whether "aA" or "Aa"? – DSM Nov 02 '12 at 18:15
  • I'd rather have the uppercase come first for any given number of the same letter – spikey273 Nov 02 '12 at 18:19

2 Answers2

4

This makes sure capital letters go first:

s = 'mqRMRsL'
result = ''.join(sorted(s, key=lambda c:(c.lower(), c)))
# LMmqRRs

This doesn't:

s = 'mqRMRsL'
result = ''.join(sorted(s, key=str.lower))
# LmMqRRs
Oleh Prypin
  • 33,184
  • 10
  • 89
  • 99
2

here is a slight alteration to BlaXpirit solution to make the sort stable:

def alphabet_cmp(a, b):
    a_lower, b_lower = a.lower(), b.lower()
    if a_lower == b_lower:
        return cmp(a, b)
    else:
        return cmp(a_lower, b_lower)

x = 'ABcdCDab'
''.join(sorted(x, cmp=alphabet_cmp))
# 'AaBbCcDd'
jcr
  • 1,015
  • 6
  • 18
  • `NameError: name 'cmp' is not defined`. `TypeError: 'cmp' is an invalid keyword argument for this function`. See [**this**](http://docs.python.org/3/whatsnew/3.0#ordering-comparisons) – Oleh Prypin Nov 02 '12 at 22:15
  • I don't know why cmp is an invalid keyword, the doc string for sorted in python 27 is "sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list" however your solution is more elegant and also stable and thus better than mine, I don't know why I didn't realize that when I quickly read your reply prior to posting, sorry – jcr Nov 03 '12 at 11:07
  • yes.. I didn't see that it was a python 3.0 thread I replied to... I just continue to make a fool of myself :) – jcr Nov 03 '12 at 11:10