Reputation: 605
I am trying to order the words of a string in a particular way: In my code below the output is "MNWdeorwy" but i would like it to be "deMNorWwy" (so i need to keep the letters ordered despite being upper o lowercases) Could you please help me to understand where I am wrong and why? Thank you
wrd = "MyNewWord"
def order_word(s):
if s == "":
return "Invalid String!"
else:
c = sorted(s)
d = ''.join(sorted(c))
return d
print order_word(wrd)
I would like to precise that my question is different from the following: How to sort the letters in a string alphabetically in Python : in fact, the answers given in the link does not consider the difference between upper and lowercases in a string.
Upvotes: 5
Views: 6687
Reputation: 20336
sorted()
sorts based off of the ordinal of each character. Capital letters have ordinals that are lower than all lowercase letters. If you want different behavior, you'll need to define your own key:
c = sorted(s, key=lambda c: (c.lower(), c.islower()))
That way, c
would be sorted by ('c', 1)
and C
is sorted by ('c', 0)
. Both come before ('d', ...)
or ('e', ...)
etc., but the capital C
is earlier (lower) than the lowercase c
.
By the way, you shouldn't say d = "".join(sorted(c))
because c
has already been sorted. Just do d = "".join(c)
Upvotes: 9
Reputation: 25023
If I understand correctly your requirements, you want to sort a string
this can be achieved, e.g.,
In [44]: a = 'zWea'
In [45]: sorted(a,key=lambda c:c.upper())
Out[45]: ['a', 'e', 'W', 'z']
In [46]:
that works because you transform momentarily individual characters during a comparison.
Forgot to mention, you can mix non-alphabetical chars in your string, but a few characters are placed between upper and lower case alphabetical chars (e.g., the ^
caret), so what you get depends on using .lower()
or .upper()
method of strings,
In [56]: sorted('abCD^',key=lambda c:c.lower())
Out[56]: ['^', 'a', 'b', 'C', 'D']
In [57]: sorted('abCD^',key=lambda c:c.upper())
Out[57]: ['a', 'b', 'C', 'D', '^']
In [58]:
Upvotes: 3
Reputation: 2056
You can also try like this
import re
def natural_sort(wrd):
convert = lambda text: int(text) if text.isdigit() else text.lower()
final = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return ''.join(sorted(wrd, key = final))
Output:
>>> natural_sort(wrd)
'deMNorwWy'
OR
You can do with third party library for this on PyPI called natsort
https://pypi.python.org/pypi/natsort
Upvotes: 1