It looks like you are going through some extra hoops here. You have a quantity that is already a perfect key. Instead of just using it, you define a comparator that recomputes and compares two of these quantities for every pair of objects, and then convert that comparator back to a key.
This seems very inefficient. Why not just define a simple key function and use it directly?
def distance_from_origin_squared(point):
return point[0]**2 + point[1]**2
points = sorted(points, key=distance_from_origin_squared)
Keep in mind that sorted
does not operate in-place, so you have to stash it somewhere. Replacing the original name if fine. If you want an in-place sort, use list.sort
instead:
points.sort(key=distance_from_origin_squared)
From a practical point of view, keys offer a number of advantages over comparators. For one thing, a key function only needs to be called once per element, while a comparator is called O(nlog(n))
times. Of course the keys are compared O(nlog(n))
times, but the comparison is usually much simpler since the values of interest are computed up front.
The main difficulty coming from C (in my case) is grasping the idea that keys do not have to be single integers, as is usually shown in examples. Keys can be any type that clearly defines the <
(or >
) operator. Lexicographical comparison of strings, lists and tuples makes it very easy to boil a complex chained comparator to a key that is just a short sequence of values.