a little bit about sorted() built-in function that builds a new sorted list from an iterable
sorted() have a key parameter to specify a function to be called on
each list element before making comparisons.
The value of the key parameter should be a function that takes a
single argument and returns a key(in this particular case it is a
tuple) to use for sorting purposes. This technique is fast because
the key function is called exactly once for each input record.
let's break the sorted function into a more readable piece of code.
def key_function(character):
print((character.isdigit() - character.islower(), character in "02468", character))
return (character.isdigit() - character.islower(), character in "02468", character)
input_string = "1949 Film Prejudice"
print(*sorted(input_string, key=key_function), sep="")
This is the intermediate list of tuple which I have contrived just for the sake of explanation of the problem.
[
(1, False, "1"),
(1, False, "9"),
(1, True, "4"),
(1, False, "9"),
(0, False, " "),
(0, False, "F"),
(-1, False, "i"),
(-1, False, "l"),
(-1, False, "m"),
(0, False, " "),
(0, False, "P"),
(-1, False, "r"),
(-1, False, "e"),
(-1, False, "j"),
(-1, False, "u"),
(-1, False, "d"),
(-1, False, "i"),
(-1, False, "c"),
(-1, False, "e"),
]
The comparison between these tuples is the key to understand how this works.
If you'll just sort this list(which uses tuple comparison to sort) you will get the desired result.
We'll go through the 3 aspects of comparison happening during (1, False, "1") > (1, False, "9")
- Integer comparison
- Boolean comparison
- Character comparison
Integer comparison
Integer comparison intuitive because it's just integers we have to deal with.
Boolean comparison
just to give the glimpse of what True was False used to be
PEP 285
(True and False constants were added to the built-ins in Python
2.2.1, but the 2.2.1 versions are simply set to integer values of 1 and 0 and aren't a different type.)
so the comparison between them is also the same as between integers.
True - False is 1 and False - True is -1.
Character comparison
These strings are being ordered by the ASCII values of their
characters (p is 112 in ASCII and P is 80).
Technically Python compares the Unicode code point (which is what ord
does) for these characters and that happens to be the same as the
ASCII value for ASCII characters.
so ultimately it also boils down to integer comparison.
Hopefully, now you'll have a good understanding of what is happening in that sorted function :)
for more information read this article on Tuple ordering and deep comparisons in Python
https://treyhunner.com/2019/03/python-deep-comparisons-and-code-readability/
All sorted lowercase letters are ahead of digits (effectively)int. If you seeTrueas1andFalseas0it should make more sense.