Chapter 7
This depends on the yield_sequence() function, which looks as follows:
def yield_sequence(rank, same_rank_iter):
head= next(same_rank_iter)
yield rank, head
yield from yield_sequence(rank, same_rank_iter)
We've written this in a way that emphasizes the recursive definition. We don't
really need to extract the head, emit it, and then recursively emit the remaining
items. While a single for statement might be shorter, it's sometimes more clear to
emphasize the recursive structure that has been optimized into a for loop.
The following are some examples of using this function to rank (and rerank) data.
We'll start with a simple collection of scalar values:
scalars= [0.8, 1.2, 1.2, 2.3, 18]
list(ranker(scalars))
[Rank_Data(rank_seq=(1.0,), raw=0.8), Rank_Data(rank_seq=(2.5,),
raw=1.2), Rank_Data(rank_seq=(2.5,), raw=1.2), Rank_Data(rank_seq=(4.0,),
raw=2.3), Rank_Data(rank_seq=(5.0,),
raw=18)]
Each value becomes the raw attribute of a Rank_Data object.
When we work with a slightly more complex object, we can also have multiple
rankings. The following is a sequence of two tuples:
pairs= ((2, 0.8), (3, 1.2), (5, 1.2), (7, 2.3), (11, 18))
rank_x= tuple(ranker(pairs, key=lambda x:x[0] ))
rank_x
(Rank_Data(rank_seq=(1.0,), raw=(2, 0.8)), Rank_Data(rank_seq=(2.0,),
raw=(3, 1.2)), Rank_Data(rank_seq=(3.0,), raw=(5, 1.2)),
Rank_Data(rank_seq=(4.0,), raw=(7, 2.3)), Rank_Data(rank_seq=(5.0,),
raw=(11, 18)))
rank_xy= (ranker(rank_x, key=lambda x:x[1] ))
tuple(rank_xy)
(Rank_Data(rank_seq=(1.0, 1.0), raw=(2, 0.8)),
Rank_Data(rank_seq=(2.0, 2.5), raw=(3, 1.2)),
Rank_Data(rank_seq=(3.0, 2.5), raw=(5, 1.2)),
Rank_Data(rank_seq=(4.0, 4.0), raw=(7, 2.3)), Rank_Data(rank_seq=(5.0,
5.0), raw=(11, 18)))