Additional Tuple Techniques
The following is how we can create an object that wraps a pair with the rank order
based on the y value:
Ranked_Y= namedtuple("Ranked_Y", ("r_y", "raw",))
def rank_y(pairs):
return (Ranked_Y(*row)
for row in rank(pairs, lambda pair: pair.y))
We've defined a namedtuple function that contains the y value rank plus the original
(raw) value. Our rank_y() function will create instances of this tuple by applying
the rank() function using a lambda that selects the y value of each pairs object.
We then created instances of the resulting two tuples.
The idea is that we can provide the following input:
data = (Pair(x=10.0, y=8.04), Pair(x=8.0, y=6.95), ...,
Pair(x=5.0, y=5.68))
We can get the following output:
list(rank_y(data))
[Ranked_Y(r_y=1.0, raw=Pair(x=4.0, y=4.26)),
Ranked_Y(r_y=2.0, raw=Pair(x=7.0, y=4.82)), ...
Ranked_Y(r_y=11.0, raw=Pair(x=12.0, y=10.84))]
The raw Pair objects have been wrapped in a new object that includes the rank.
This isn't all we need; we'll need to wrap this one more time to create an object that
has both x and y rank information.
Rewrapping instead of state changing
We can use a namedtuple named Ranked_X that contains two attributes: r_x and
ranked_y. The ranked_y attribute is an instance of Ranked_Y that has two attributes:
r_y and raw. Although this looks simple, the resulting objects are annoying to work
with because the r_x and r_y values aren't simple peers in a flat structure. We'll
introduce a slightly more complex wrapping process that produces a slightly
simpler result.
We want the output to look like this:
Ranked_XY= namedtuple("Ranked_XY", ("r_x", "r_y", "raw",))