【Python 第33课】处理文件中的数据


我们已经知道了如何读取和写入文件。有了这两个操作文件的方法,再加上对文件内容的处理,就能写一些小程序,解决不少日常的数据处理工作。

 

比如我现在拿到一份文档,里面有某个班级里所有学生的平时作业成绩。因为每个人交作业的次数不一样,所以成绩的数目也不同,没交作业的时候就没有分。我现在需要统计每个学生的平时作业总得分。

 

记得我小的时候,经常有同学被老师喊去做统计分数这种“苦力”。现在电脑普及了,再这么干就太弱了。用python,几行代码就可以搞定。

 

看一下我们的文档里的数据:

文件 scores.txt

刘备 23 35 44 47 51
关羽 60 77 68
张飞 97 99 89 91
诸葛亮 100

注意:为了减少麻烦,请保证文件中没有多余的空行。另外,因为windows系统默认会隐藏文件类型,所以请确保你创建的文件名正确,不要多加了后缀,误存为 scores.txt.txt

 

1.先把文件读进来,在这里,由于有中文字符,因此需要对字符进行编码,以免出现报错。

 

在 windows 中,如果用记事本打开,并且将这些文字一个个手动输入,默认中文编码为 gbk,因此需要:

f = open('scores.txt', encoding='gbk')

题外话:我并不建议在学习编程时使用windows默认的记事本,它会在文字编码上给你带来很多不必要的麻烦。推荐使用可以方便控制编码的notepad++或sublime text。

 

而如果是 Mac 或 Linux 系统,或者直接复制了我的文本(浏览器的中文编码多使用 utf-8),则使用了 utf-8 编码,因此需要:

f = open('scores.txt', encoding='utf-8')

 

这只是很粗略的总结,编码的问题一直都是编程的一大难题,如果出现报错,就换一种编码再试试。我们之后的教程都是在 windows 系统中的,所以使用 gbk 编码(但不排除你的系统可能是 utf8)。

 

2.取得文件中的数据。因为每一行都是一条学生成绩的记录,所以用readlines,把每一行分开,便于之后的数据处理:

lines = f.readlines()
f.close()

提示:在程序中,经常使用print来查看数据的中间状态,可以便于你理解程序的运行。比如这里你可以print (lines),看一下内容被存成了什么格式。

 

3.对每一条数据进行处理。按照空格,把姓名、每次的成绩分割开:

for line in lines:
   data = line.split()

这里用到之前 28.字符串的分割 课程中介绍过的 split 方法。

 

接下来的4、5两个步骤都是针对一条数据的处理,所以都是在for循环的内部。

 

4.整个程序最核心的部分到了。如何把一个学生的几次成绩合并,并保存起来呢?我的做法是:对于每一条数据,都新建一个字符串,把学生的名字和算好的总成绩保存进去。最后再把这些字符串一起保存到文件中:

 

sum = 0
score_list = data[1:]  # 学生各门课的成绩列表
for score in score_list:
   sum += int(score)
result = '%s\t: %d\n' % (data[0], sum)  # 名字和总分

 

这里几个要注意的点:

  1. 对于每一行分割的数据,data[0]是姓名,data[1:]是所有成绩组成的列表。
  2. 每次循环中,sum都要先清零
  3. score是一个字符串,为了做计算,需要转成整数值int。
  4. result中,我加了一个制表符\t和换行符\n,让输出的结果更好看些。

 

5.得到一个学生的总成绩后,把它添加到一个list中。

results.append(result)

 

results需要在循环之前初始化 results = []

 

6.最后,全部成绩处理完毕后,把results中的内容保存至文件。因为results是一个字符串组成的list,这里我们直接用writelines方法:

output = open('result.txt', 'w', encoding='gbk')
output.writelines(results)
output.close()

 

以下是完整程序,把其中print前面的注释符号去掉,可以查看关键步骤的数据状态。

f = open('scores.txt', encoding='gbk')
lines = f.readlines()
# print(lines)
f.close()

results = []
 
for line in lines:
   # print (line)
   data = line.split()
   # print (data)

   sum = 0
   score_list = data[1:]
   for score in score_list:
       sum += int(score)
   result = '%s \t: %d\n' % (data[0], sum)
   # print (result)
   
   results.append(result)

# print (results)
output = open('result.txt', 'w', encoding='gbk')
output.writelines(results)
output.close()

 

 

大功告成,打开文件检验一下结果吧。

 

建议你把 print 前面的注释依次去掉,一步一步地去查看结果,理解每一步的作用。

 

来源:Crossin的编程教室