【问题标题】:Sort names and scores of students within x points of max score?在最高分的 x 分内对学生的姓名和分数进行排序?
【发布时间】:2017-02-05 02:18:50
【问题描述】:

我有一个采用这种格式的 csv 文件,其中包含一个带有姓氏的列、另一列带有名字的列和另一列带有平均值的列。

Word1       Word2        Points
World       Hello        85
Test1       Test1        81
Test2       Test2        91 (etc.)

我希望程序找到并打印在最高分 5 分以内的学生的 word1、word2 和分数。 (因此,如果最高分是 91,那么将列出从 86(包括)到 91 的所有名称和所有分数。

到目前为止,我有这个:

import csv
row = []
in = open("scoreaverage.csv", "r")
reading = csv.reader(in)
for line in reading:
    if reading.line_num > 1:  #to skip the header of the csv
        row.append(line)
        ###not sure with the logic from here out to sort all the rows within 5 points of the maximum score

我是一名业余爱好者,因此非常感谢任何帮助! (不能使用 pandas 或任何那些很酷的快捷方式)

【问题讨论】:

  • CSV 字段之间有逗号。您在上面显示的示例文件没有。它是哪一个?这会影响解决方案。
  • 这肯定是一个csv文件。字段之间有逗号。我只是想像您在 excel 中看到的那样显示它。

标签: python sorting csv


【解决方案1】:

您想要的第一步是获得最高分。您有一个行列表,因此您可以浏览这些行。 (我将您的 row 重命名为 rows,因为它是行列表,而不是单行):

from functools import reduce
# ... other code
max_score = reduce(lambda best_score, curr_row: max(float(curr_row[2]), best_score), rows, float('-inf')) 

现在您要根据分数是否在最大值的 5 分之内进行过滤:

cutoff = 5
result = list(filter(lambda row: float(row[2]) >= max_grade - cutoff, rows))

就我个人而言,我更喜欢 Python 的函数式风格,但你当然可以用循环等来做类似的事情。

max_score 的另一种方法:

max_score = max([row[2] for row in rows])

【讨论】:

    【解决方案2】:

    这是一个简短的示例,说明如何使用 sorted 按第三列对行进行排序:

    import csv
    
    with open('test.csv') as f:
        reader = csv.reader(f, delimiter='\t')
        next(reader)    # Skip column names
        rows = sorted(reader, key=lambda x: int(x[2]), reverse=True)
        print(*rows, sep='\n')
    

    输出:

    ['Test2', 'Test2', '91']
    ['World', 'Hello', '85']
    ['Test1', 'Test1', '81']
    

    sorted 的第一个参数是一个要排序的迭代。方便reader 是一个可迭代对象,因此一旦我们删除了包含列名的第一行,我们就可以将其作为参数传递。

    第二个参数是key函数,它从iterable中获取一个元素作为参数并返回key用于排序。因为我们想按第三列排序,所以一旦我们将它转​​换为int,我们就会返回它。如果我们跳过转换,得分为 9 的学生将列在得分为 89 的学生之前,因为'9' 按字母顺序大于'89'

    第三个参数只是一个标志,告诉我们希望结果以相反的顺序排列,最大的项目在前。

    【讨论】:

    • 也添加剩余的代码。 max = rows[0][2], desired_rows = filter(lambda x: x >= max-5, rows)
    • @MYGz 这看起来像是一个学校作业,所以我只是想帮助解决问题所在的特定部分,按第三列对行进行排序。
    • 好吧。 csv 也无效。分隔符似乎不是恒定的。有没有办法在 csv 模块中使用正则表达式分隔符?
    • @MYGz Regex 不能用,可以从Python docs 看到选项。我的猜测是分隔符最初是制表符,而不是转换为介于两者之间的空格。
    猜你喜欢
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2015-05-10
    • 2019-09-21
    • 2018-09-12
    • 1970-01-01
    • 2021-10-18
    相关资源
    最近更新 更多