Pointing at sorted in VS Code, the following popup appears:
This contains lots of syntax elements I don't know from Python, such as /, *, _T, @; and coming from C , it looks as if SupportsRichComparison is similar to a C 20 Concept but what is it really?
Also, how do I distinguish what the two different overloads are for?
CodePudding user response:
That is a bit of a train wreck. It boils down to this:
If you only pass an iterable to
sorted(so that the keyword argumentkeygets its default valueNone), then there has to be a way to compare the elements to determine an ordering.If you do provide a
keyargument, then you can have an arbitrary iterable, because the value ofkeywill be used to "map" the values to things that can be compared.
Regular parameters can be specified via positional arguments or keyword arguments.
Parameters that precede / are positional-only: you cannot specify values for them using keywords arguments. (sorted(__iterable=[1,2,3]) would be illegal.)
Parameters that follow * are keyword-only: you can only specify values for them using keyword arguments. (sorted([1,2,3], f) would be illegal.)
_T is a type variable: it represents a specific but unknown type, basically used to tie the type hint for __iterable to the type hints for key.
SupportsRichComparison looks to be a typing.Protocol, which means it is basically an abstract base class that asserts its subclasses provide definitions for __lt__ et al. Note that either the elements of __iterable are instance of SupportsRichComparison, or they are instances of some class _T that key knows how to convert to instances of SupportsRichComparison.
I am at a loss for how to explain @. It doesn't conform to any actual Python syntax that I am aware of; it might simply be some sort of conventional separator used to construct a type variable from some other pieces of information.
As a concrete example, consider complex numbers. Two complex numbers are not directly comparable:
>>> sorted([3 4j, 6-7j])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'complex' and 'complex'
But integers are comparable:
>>> sorted([4, -7])
[-7, 4]
So if you had some function that could map 3 4j to 4 and 6-7j to -7, you could sort the original list of complex numbers.
>>> sorted([3 4j, 6-7j], key=lambda x: x.imag)
[(6-7j), (3 4j)]

