We'll break the rank ordering problem into two parts. First, we'll look at a generic, higher-order function that we can use to assign ranks to either the x or y value of a Pair object. Then, we'll use this to create a wrapper around the Pair object that includes both x and y rankings. This will avoid a deeply nested structure.
The following is a function that will create a rank order for each observation in a dataset:
from typing import Callable, Tuple, List, TypeVar, cast, DictD_ = TypeVar("D_")K_ = TypeVar("K_")def rank( data: Iterable[D_], key: Callable[[D_], K_]=lambda obj: cast(K_, obj) ) -> Iterator[Tuple[float, D_]]: def build_duplicates( duplicates: Dict[K_, List[D_]], data_iter: Iterator[D_], key: Callable[[D_], ...