在Python中使用CSV格式文件的问题

0 投票
1 回答
38 浏览
提问于 2025-04-14 17:24

我在做一个用Python处理CSV文件的项目,使用了csv库和统计的平均值函数,但在输出结果时遇到了问题。我也不知道为什么会这样。下面是我的代码:

def calculate_averages(input_file_name, output_file_name):
    fileName = input_file_name
    grades = []
    average = OrderedDict()
    with open(fileName, newline ='') as csvfile:
        reader = csv.reader(csvfile)
        try:
            for lines in reader:
                name = lines[0]
                for row in lines[1:]:
                    grades.append(int(row))
                grades_mean = mean(grades)
                average[name] = grades_mean
                #print(lines)
        except csv.Error as e:
            exit(f"file name {fileName}, line {reader.line_num} : {e}")
        with open(output_file_name, 'w', newline='') as output:
            writer = csv.writer(output)
            for key, values in average.items():
                writer.writerow([key, values])

我试图从本地读取一个CSV文件,然后把名字和成绩分开,把成绩转换成浮点数放进列表里,计算每个人的平均成绩,并把名字和平均成绩放在一个有序字典里。这个方法其实是可以工作的,但计算出来的平均值不准确。

1 个回答

0

这里的问题在于,grades 这个变量在循环外面,所以它会把所有名字的成绩都累加起来。你需要把它放到 for ... in reader 循环里面。更好的是,我们可以用列表推导式来简化代码。下面是一种解决方法:

import csv
from statistics import mean


def calculate_averages(input_file_name, output_file_name):
    average = []
    with open(input_file_name) as stream:
        reader = csv.reader(stream)
        for row in reader:
            name = row[0]
            grades = [float(value) for value in row[1:]]
            grades_mean = mean(grades)
            average.append((name, f"{grades_mean:>0.1f}"))

    with open(output_file_name, "w") as stream:
        writer = csv.writer(stream)
        writer.writerows(average)

注意事项

  • 我把 lines 改成了 row:因为 lines 这个名字容易让人误解,它其实只代表一行文本。
  • 我又把 row 改成了 value:同样,row 这个名字也不太准确,因为它代表的是一行中的一个数字。
  • 我去掉了 try/except 结构:如果出现错误,输出的信息会比单纯打印错误信息更有帮助。
  • 我去掉了 OrderedDict 的使用,因为简单的元组就足够了。我假设名字不会重复。
  • 我把成绩格式化为 0.1f 的样式,这样输出看起来更整齐。
  • 我把 with open(output ... 的缩进去掉,让代码层次不那么深。
  • 我把 .writerow 替换成了 .writerows

撰写回答