如何用Python的itertools计算F1赛事车手夺冠的所有排位组合
问题分析
你当前使用的itertools.product是生成两个列表的笛卡尔积,会出现同一名次分配给多个车手、同一车手对应多个名次的问题,不符合「每个车手分配唯一对应名次」的全排列需求。同时原代码缺少itertools库的导入声明。
实现逻辑调整方案
你需要使用itertools.permutations生成全排列,保证每个名次/车手在单组结果中仅出现一次,以下提供两种常用实现思路:
思路1:直接生成车手排位全排列(更适合计算积分)
生成的每个排列的顺序对应从第1名到第20名的车手,无需额外配对逻辑:
import itertools def Sim(): drivers = ["Lewis Hamilton","Valteri Bottas","Max Verstappen","Sergio Perez","Lando Norris","Daniel Riccardo","Carlos Sainz","Charles Lecerc","Pierre Gasly","Yuki Tsunoda","Kimi Raikonnen","Antonio Giovnazzi","Sebastian Vettel","Lance Stroll","Fernando Alonso","Estaban Ocon","George Russel","Nicholas Latifi","Mick Schumacher","Nikita Mazepin"] # 迭代处理每个排位组合,不要直接转list避免内存溢出 for standing in itertools.permutations(drivers): # standing[0] 为第1名,standing[1]为第2名,以此类推,可在此处添加积分计算逻辑 print(standing)
思路2:生成车手-名次配对字典(更方便查询指定车手排名)
对名次列表生成全排列后,和车手列表按索引一一配对生成字典:
import itertools def Sim(): drivers = ["Lewis Hamilton","Valteri Bottas","Max Verstappen","Sergio Perez","Lando Norris","Daniel Riccardo","Carlos Sainz","Charles Lecerc","Pierre Gasly","Yuki Tsunoda","Kimi Raikonnen","Antonio Giovnazzi","Sebastian Vettel","Lance Stroll","Fernando Alonso","Estaban Ocon","George Russel","Nicholas Latifi","Mick Schumacher","Nikita Mazepin"] # 建议将名次转为整数方便后续积分计算 pos = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] # 迭代处理每个名次排列 for pos_perm in itertools.permutations(pos): standing = dict(zip(drivers, pos_perm)) # 可在此处添加总冠军判定逻辑,符合条件的结果再保存 print(standing)
注意事项
20个元素的全排列总量为20! ≈ 2.43e18,直接将所有排列存入列表会占用极高内存甚至直接导致程序崩溃,建议迭代处理每个排列,每生成一组就直接计算总冠军归属,仅保留符合条件的结果即可。
内容的提问来源于stack exchange,提问作者Josh Cooke
相关产品推荐
相关产品推荐

