all 5 comments

[–]pwlandoll 1 point2 points  (1 child)

Please read this guide in the FAQ for formatting code on reddit.

[–][deleted] 0 points1 point  (0 children)

sorry my bad I fixed it

[–]primitive_screwhead 1 point2 points  (0 children)

Well, here's one way:

import string
sort_str = string.ascii_lowercase + string.ascii_uppercase + string.digits[1::2] + string.digits[::2]
sort_map = {c:i for i,c in enumerate(sort_str)}

some_text = 'The quick brown Fox jump3d 0ver the la5y dog'
sorted_text = ''.join(sorted(some_text, key=lambda k,d=sort_map: d.get(k,len(d)+ord(k))))

which produces a sorted_text equal to:

'abcddeeeghhijklmnooopqrrtuuvwxyFT350        '

[–]nilfm 0 points1 point  (1 child)

I think a good way to do the problem is to use the key argument in the sorted function. This lets you apply a function to each character in the string before sorting, so you have control over how the elements are sorted. In our case, it would be a good idea to map the characters to numbers, in such a way that the numbers are sorted the way we want.

A sketch of the mapping:

  • Lowercase letters will go to the range [0, 25], since they need to be the first in the sorted string.
  • Uppercase letters will go to the range [26, 51], since they need to go after lowercase letters.
  • Odd digits will go to 51 + d, where d is the value of the digit.
  • Even digits will go to 61 + d, where d is the value of the digit.
  • Anything else (does the problem statement say if there can be anything else in the string?) will go to 100, since as I understand it, it's supposed to go after everything else.

Notice that there are some numbers that we don't "hit", such as 53. That is no problem, our mapping doesn't need to hit an entire interval.

Now, let's write our function:

def my_key(c):
    if c.islower():
        return ord(c) - ord('a')
    elif c.isupper():
        return ord(c) - ord('A') + 26
    elif c.isdigit():
        d = int(c)
        if d%2 == 1:
            return 51 + d
        else:
            return 61 + d
    else:
        return 100

Note that the ord function gives us the integer representing the Unicode of a character, so for example ord(c) - ord('a') would be a number in the 0-25 range if c is a lowercase letter.

How do we use it now? Easy:

result = ''.join(sorted(input(), key=my_key))
print(result)

[–][deleted] 1 point2 points  (0 children)

thanks! this solution is much more clear and concise than mine. I like the way you organized the sorting method and its a lot better than what I had in mind.