【问题标题】:Sorting a dictionary by average of list in value按值列表的平均值对字典进行排序
【发布时间】:2015-05-31 14:16:44
【问题描述】:

我有一个字典,其中键是名称,值是最多 3 个整数的列表(这些是命名人员的分数):

classScores={
    'Bob':[1, 6, 3],
    'Jim':[6, 10, 3],
    'Fred':[0, 2]
}

我需要按分数的平均值(最高优先)排序打印它。我已经创建了一个工作代码来做到这一点:

classAverages={}
for student in classScores:
    classAverages[student]=sum(classScores[student])/len(classScores[student])
for student in sorted(classAverages, key=classAverages.get, reverse=True):
    print(student, "Average:", sum(classScores[student])/len(classScores[student]))

但是,我觉得这是低效的,因为它使用 2 个for 循环,因此必须通过每个学生两次。因此,我正在寻找将排序合并到第二个循环(大概是其排序函数)的建议。


更新:我使用了 lambda,但我在 for 循环之前定义了它,以便我也可以使用它来打印平均值:

classAverages=lambda student: sum(classScores[student]) / len(classScores[student])
for student in sorted(classScores, key=classAverages, reverse=True):
    print(student, "Average:", classAverages(student))

【问题讨论】:

    标签: python sorting python-3.x dictionary


    【解决方案1】:

    您可以在key 函数中计算每个学生的平均值:

    for student in sorted(classScores, key=lambda k: sum(classScores[k]) / len(classScores[k]), reverse=True):
    

    但是,使用两个循环的效率只是略微降低;您只增加了每个学生的固定成本来确定订单。当显示平均值时,您错过了在第二个循环中重复使用该平均值的机会:

    classAverages={}
    for student in classScores:
        classAverages[student] = sum(classScores[student]) / len(classScores[student])
    
    for student in sorted(classAverages, key=classAverages.get, reverse=True):
        print(student, "Average:", classAverages[student])
    

    您可以在生成器表达式中遍历字典项以计算平均值,对这些平均值进行排序,然后在一个操作中显示计算的平均值:

    student_averages = ((sum(scores) / len(scores), s) for s, scores in classScores.items())
    
    for average, student in sorted(student_averages, reverse=True):
        print(student, "Average:", average)
    

    生成器以(average, student) 对生成数据以简化排序(我们现在不需要key 来挑选第二个值)。

    【讨论】:

    • 谢谢!使用 lambda 有效(加上reverse=True)。而且我从没想过要重用 classAverages 数据!
    • "memoizing" classAverages.get 将是另一种避免重新计算的方法,同时保持原来的方法,对吧?
    • @alexis:对。您可以对classAverages.items() 进行排序(以lambda pair: pair[1]operator.itemgetter(1) 作为关键函数)。然后你就有了student, average 元组的排序序列。
    • @DanielO'Toole 生成器解决方案看起来比您的 lambda 更好,并且更高效
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2019-12-30
    • 2021-08-25
    • 2010-09-09
    相关资源
    最近更新 更多