使用enumerate为NFL球队数据排名时如何给相同数值赋予相同排名
实现NFL球队并列竞赛排名的方案
你需要的排名规则属于竞赛排名(即并列名次占对应位次,后续名次顺延跳过),原来直接用enumerate计数的方式无法识别数值相同的条目,需要手动跟踪当前排名、上一条统计值两个变量实现。
直接适配现有逻辑的修改版代码
for team in TeamName.objects.filter(league__name='NFL'): # 先拿到按场均得分倒排的统计列表 stats_list = NFLTeamStats.objects.all().values('name', 'avg_points').order_by('-avg_points') current_rank = 1 prev_score = None for idx, value in enumerate(stats_list, start=1): # 和上一条得分不同时,更新当前排名为当前遍历序号 if prev_score is not None and value['avg_points'] != prev_score: current_rank = idx # 匹配到对应球队时赋值排名 if value['name'] == team.pk: avg_points_rank = current_rank break # 记录上一条的得分 prev_score = value['avg_points']
性能优化建议
你现在的实现是每个球队都遍历一次全联盟统计数据,时间复杂度为O(n²),可以优化为一次遍历算出所有球队的排名字典,再批量更新:
stats_list = NFLTeamStats.objects.all().values('name', 'avg_points').order_by('-avg_points') rank_dict = {} current_rank = 1 prev_score = None for idx, value in enumerate(stats_list, start=1): if prev_score is not None and value['avg_points'] != prev_score: current_rank = idx rank_dict[value['name']] = current_rank prev_score = value['avg_points'] # 后续直接从rank_dict取所有球队的排名即可 for team in TeamName.objects.filter(league__name='NFL'): avg_points_rank = rank_dict[team.pk] # 其余存储逻辑
内容的提问来源于stack exchange,提问作者Ryan Thomas
相关产品推荐
相关产品推荐

