如何按升序对这个浮点数值列表进行排序?

Posted

技术标签:

【中文标题】如何按升序对这个浮点数值列表进行排序?【英文标题】:How to sort this float list of numerical values in ascending order? 【发布时间】:2016-03-08 19:18:27 【问题描述】:

我已经能够在我的 CSV 文件中为每个人导入 3 个分数(或数字) 并让它计算出每个人的三个分数的平均值,但我接下来需要做的是将输出中显示的平均值列表从高到低排序。我到处搜索,我尝试的所有东西都收到了“浮动”错误。

from collections import defaultdict, deque
with open("highscores.csv", "r+")as file:
    file.seek(0)
    scores = file.readlines()
user_scores = defaultdict(lambda:deque(maxlen=3))
for line in scores:
    name, score = line.rstrip('\n').split(',')
    score = int(score)
    user_scores[name].append(score)

for name in user_scores:
    avg = (user_scores[name])
    x = sorted(avg)
    avg2 = sum(x) / float(len(x))
    print(name, avg2)

输出:

Odis 22.0
Vance 20.0
John 26.0
Marinda 25.0
Shenita 18.0
Marquitta 24.0
Concepcion 17.0
Robby 23.0
Valda 19.0
Ernesto 21.0
Jack 5.0

我的 CSV 文件如下所示:

Jack    4
Jack    5
Jack    6
Concepcion  7
Shenita 8
Valda   9
Vance   10
Ernesto 11
Odis    12
Robby   13
Marquitta   14
Marinda 15
John    16
Concepcion  17
Shenita 18
Valda   19
Vance   20
Ernesto 21
Odis    22
Robby   23
Marquitta   24
Marinda 25
John    26
Concepcion  27
Shenita 28
Valda   29
Vance   30
Ernesto 31
Odis    32
Robby   33
Marquitta   34
Marinda 35
John    36

【问题讨论】:

你快到了。使用每个名称及其平均值创建一个新字典,并对其进行排序:***.com/q/613183/584846 【参考方案1】:

您对 avg 进行排序的那一行是不必要的 - 毕竟这些是一个人的分数,您按什么顺序求和并不重要。您要做的是在计算完所有平均值后对所有条目进行排序,因此您需要收集这些条目。如果您希望根据平均值对它们进行排序,请使用以平均值作为第一个字段的元组,这样 sorted 将完全符合您的要求:

# The list that will hold the pairs of
# average score and name
avgs = []

# Your initial loop
for name in user_scores:
    x = user_scores[name]

    # Just collect the pair
    avgs.append((sum(x) / float(len(x)), name)

# Now sort it
avgs = sorted(avgs)

# Print it
for avg, name in avgs:
    print (name, avg)

然而,一种更 Pythonesque 的方式是使用列表推导:

# A function for the average
def average(lst):
    return sum(lst) / float(len(lst))

# The averages as list comprehension    
avgs = sorted((average(scores), name)
              for name, scores in user_scores.items())

# Print it
for avg, name in avgs:
    print (name, avg)

这假设您使用的是 Python 3,对于 Python 2,请使用 iteritems()viewitems()

【讨论】:

谢谢第一个完美的工作 您可以使用生成器表达式而不是列表推导式。换句话说,sorted((average(scores), name) for name, scores in user_scores.items()) 没有方括号。 你是对的,当然,我只是使用列表推导是为了与收集列表的示例保持连续性。但由于 OP 还是使用了第一个版本,我将编辑源代码以使用生成器。【参考方案2】:

假设 Python 3…

在您的第二个for 循环中,如果您在计算平均值的同时打印它们,那么您不可能以所需的顺序打印它们。你需要把它分成两个阶段。

计算平均分:

avg_user_scores = 
    user: sum(map(float, scores))/len(scores)
    for user, scores in user_scores.items()

然后打印出来,降序排列:

for name, score in sorted(avg_user_scores.items(), key=itemgetter(1), reverse=True):    
    print(name, score)

operator.itemgetter(1) 是一种获取元组第二个元素(即lambda t: t[1])的方法——这是平均分数。


整个程序:

from collections import defaultdict, deque
from operator import itemgetter

user_scores = defaultdict(lambda: deque(maxlen=3))
with open('highscores.csv') as file:
    for line in file:
        name, score = line.split(',')
        user_scores[name].append(float(score))
avg_user_scores = 
    user: sum(scores) / len(scores)
    for user, scores in user_scores.items()

for name, score in sorted(avg_user_scores.items(), key=itemgetter(1), reverse=True):    
    print(name, score)

【讨论】:

【参考方案3】:

平均每个人的三个分数。将值放入字典中(关键是人)。调用 sorted() 方法。

【讨论】:

以上是关于如何按升序对这个浮点数值列表进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

浮点数在c中的基数排序

alpha 对具有相同整数值且应按升序排列的列表进行排序[重复]

按升序对groupby中的浮点值进行排序[重复]

js中如何判断两个浮点数是不是相等

如何根据信号强度按升序对 getScanResults() 列表进行排序?

浮点数的十六进制表示