如何在Python 3中为嵌套排行榜实现密集排名并转换为字典
问题描述
我有一个嵌套的排行榜数据,示例如下:
[[100, 100, 50, 40, 40, 20, 10, 5], [100, 100, 50, 40, 40, 25, 20, 10]]
我希望采用**Dense Order Ranking(密集排名)**方法计算该排行榜的排名,并将每个子列表转换为以分数为键、排名为值的字典,示例输出如下:
[{100:1,100:1,50:2,40:3,40:3,20:4,10:5,5:6},{100:1,100:1,50:2,40:3,40:3,25:4,20:5,10:6}]
请问如何使用Python 3实现这一需求?
解决方案
先提个小细节:你给出的示例输出在Python里是不合法的——字典的键必须是唯一的,重复的键会被自动覆盖。所以我们会实现两种符合Python语法的版本,分别对应不同的使用场景:
版本1:生成唯一分数映射排名的字典
这个版本适合需要快速查询某一分数对应排名的场景,每个分数只保留一条排名记录:
def dense_rank_unique_dict(rank_lists): result = [] for scores in rank_lists: # 提取唯一分数并按降序排序,确定排名顺序 sorted_unique_scores = sorted(set(scores), reverse=True) # 构建分数到排名的映射,排名从1开始计数 score_rank_map = {score: idx + 1 for idx, score in enumerate(sorted_unique_scores)} result.append(score_rank_map) return result # 测试示例数据 input_scores = [[100, 100, 50, 40, 40, 20, 10, 5], [100, 100, 50, 40, 40, 25, 20, 10]] output_unique = dense_rank_unique_dict(input_scores) print(output_unique)
输出结果:
[{100: 1, 50: 2, 40: 3, 20: 4, 10: 5, 5: 6}, {100: 1, 50: 2, 40: 3, 25: 4, 20: 5, 10: 6}]
版本2:生成保留所有元素的排名列表(元组形式)
如果你需要完全贴合示例里“每个元素对应一个排名”的逻辑,可以用元组列表代替字典,这样能保留原列表的所有元素对应关系:
def dense_rank_element_list(rank_lists): result = [] for scores in rank_lists: sorted_unique_scores = sorted(set(scores), reverse=True) score_rank_map = {score: idx + 1 for idx, score in enumerate(sorted_unique_scores)} # 遍历每个分数,生成(分数, 排名)的元组列表 rank_list = [(score, score_rank_map[score]) for score in scores] result.append(rank_list) return result output_elements = dense_rank_element_list(input_scores) print(output_elements)
输出结果:
[[(100, 1), (100, 1), (50, 2), (40, 3), (40, 3), (20, 4), (10, 5), (5, 6)], [(100, 1), (100, 1), (50, 2), (40, 3), (40, 3), (25, 4), (20, 5), (10, 6)]]
代码逻辑说明
- 去重排序:对每个子列表的分数去重后降序排序,这样就能按从高到低的顺序确定每个分数的排名层级。
- 构建映射表:用字典推导式给每个排序后的分数分配排名(索引+1是因为排名从1开始,而Python默认索引从0开始)。
- 生成结果:根据需求选择生成唯一分数的字典,或者遍历原列表生成每个元素的排名元组。
内容的提问来源于stack exchange,提问作者user9342203
相关产品推荐
相关产品推荐

