I have the following:
sorted( ("A","a","b","B","CC","c"), key=lambda x: x.lower() )
Which gives:
['A', 'a', 'b', 'B', 'c', 'CC']
How do I sort it like this:
['a', 'A', 'b', 'B', 'c', 'CC']
where if there are two values the same, the lower form comes first - a before A.
I'm guessing I do something like this:
sorted( ("A","a","b","B","CC","c"), key=lambda x: (x.lower(),x) )
but this gives A before a:
['A', 'a', 'B', 'b', 'c', 'CC']
How do I do the opposite?
UPDATE
To clarify things further, the following strings: ["A","a","aA","aa"] should be sorted as:
["a","A","aa","aA"]
So "aa" before "aA" and "aaA" before "aAa" etc.
So:
lst = ["A","aA","aa","aaa","aAa","aaA","b","B","CC","c"]
should sort to:
['A', 'aa', 'aA', 'aaa', 'aaA', 'aAa', 'b', 'B', 'c', 'CC']
You could do:
lst = ["A","a","b","B","CC","c"]
result = sorted(lst, key= lambda x: (x.lower(), not x.islower()))
print(result)
Output
['a', 'A', 'b', 'B', 'c', 'CC']
UPDATE
Given the new you examples you could use the following key:
lst = ["A", "aA", "aa", "aaa", "aAa", "aaA", "b", "B", "CC", "c"]
result = sorted(lst, key=lambda x: (x.lower(), ''.join(str(c.isupper()) for c in x)))
print(result)
Output
['A', 'aa', 'aA', 'aaa', 'aaA', 'aAa', 'b', 'B', 'c', 'CC']
For the other example (["A","a","aA","aa"]
) it gives:
['a', 'A', 'aa', 'aA']
Here is one way:
sorted( lst, key=lambda x: (x.lower(), *map(str.isupper, x)) )
#['A', 'aa', 'aA', 'aaa', 'aaA', 'aAa', 'b', 'B', 'c', 'CC']
First sort by case insensitive letter. Then call str.upper
on all the characters of each string as the second sort condition. This will rank lower case letters first for the same length strings.
Python 2 Version
The above syntax only works in python3, but you can equivalently do the following in python2:
sorted( lst, key=lambda x: ((x.lower(),) + tuple(map(str.isupper, x))) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With