9.6.4 3个CSV 文件的写入 读取 汇总

任务1
步骤1:新建【花名册】文件夹

# 导入os 模块   
import os   
# mkdir:新建文件夹  
os.mkdir('花名册')   

代码运行后,左侧有了新的【花名册】文件夹。

27_花名册

任务2
在【花名册】文件夹中新建3个csv 文件,用字典的形式写入内容。

# 导入模块
import csv 

# 设置表头
head = ['姓名','性别','学号']  

# 设置字典存储学员信息
dict1 = {'姓名': '张三', '性别': '女', '学号': '00001'}
dict2 = {'姓名': '李四', '性别': '女', '学号': '00002'}
dict3 = {'姓名': 'nike', '性别': '男', '学号': '00003'}
dict4 = {'姓名': 'mike', '性别': '男', '学号': '00004'}
dict5 = {'姓名': '王五', '性别': '女', '学号': '00005'}
dict6 = {'姓名': '赵六', '性别': '男', '学号': '00006'}

# 以从头写入的方法w 打开文件,将返回的文件对象赋值给变量f
# newline=''表示不要空行
with open ('./花名册/1班花名册.csv','w',encoding='utf-8',
newline='') as f :
    # 参数f 是文件对象
    # 参数fieldnames=head表示表头 
    csv_target = csv.DictWriter(f,fieldnames=head)
    # 写入表头
    csv_target.writeheader( )
    # 一次性写入多行,参数是列表
    csv_target.writerows([dict1,dict2])

with open ('./花名册/2班花名册.csv','w',encoding='utf-8',
newline='') as f :
    csv_target = csv.DictWriter(f,fieldnames=head)
    csv_target.writeheader( )
    csv_target.writerows([dict3,dict4])

with open ('./花名册/3班花名册.csv','w',encoding='utf-8',
newline='') as f :
    csv_target = csv.DictWriter(f,fieldnames=head)
    csv_target.writeheader( )
    csv_target.writerows([dict5,dict6])

代码运行后,成功新建了3个CSV文件,并写入字典内容,如下图所示:

28_写入花名册png

file [faɪl]:文件。
folder[ˈfəʊldə]:文件夹。
fieldnames:字段名称即表头。
newline[n'ju:laɪn]:换行、新行。
header [ˈhedə]:页眉,标题。
writeheader:写表头。
row[raʊ]:一行、一排。
writerow:写入一行。
writerows:写入多行。

./花名册/2班花名册.csv./花名册/2班花名册

任务3
在汇总文件之前,我们先检查3个csv 文件中的内容,这里将3个文件的信息用字典的形式输出。

# 导入模块
import csv 

# 以只读模式r用open函数打开文件,将返回的文件对象赋值给变量f
with open ('./花名册/1班花名册.csv','r',encoding='utf-8') as f:
    csv_target = csv.DictReader(f)
    for row in csv_target:
        print(row)

with open ('./花名册/2班花名册.csv','r',encoding='utf-8') as f:
    csv_target = csv.DictReader(f)
    for row in csv_target:
        print(row)

with open ('./花名册/3班花名册.csv','r',encoding='utf-8') as f:
    csv_target = csv.DictReader(f)
    for row in csv_target:
        print(row)

【终端输出】

{'姓名': '张三', '性别': '女', '学号': '00001'}
{'姓名': '李四', '性别': '女', '学号': '00002'}
{'姓名': 'nike', '性别': '男', '学号': '00003'}
{'姓名': 'mike', '性别': '男', '学号': '00004'}
{'姓名': '王五', '性别': '女', '学号': '00005'}
{'姓名': '赵六', '性别': '男', '学号': '00006'}

代码运行后,输出了6个字典。

大家观察上述代码,发现除了open函数的第一个参数外,其它的代码都是一样的,那我们是否可以对代码进行优化? 这里我们使用for循环来优化上面的代码。

# 导入库
import os 
import csv 

# 文件夹路径='./花名册'
folder_path = './花名册/'

# 用listdir查看花名册文件夹中的文件
# 输出的数据赋值给变量file_list
file_list = os.listdir(folder_path)
# 输出的数据类型是列表
print(file_list)

# for循环遍历file_list,得到每个文件的文件名
for file_name in file_list:
    # 将文件名和文件夹路径进行拼接,得到每个文件的路径
    file = folder_path+file_name 
    # 输出3个csv文件的相对路径
    print(file)
    
    # 用只读模式r打开文件
    with open (file,'r',encoding='utf-8') as f:
        csv_target = csv.DictReader(f)
        for row in csv_target:
            print(row)

【终端输出】

['1班花名册.csv', '2班花名册.csv', '3班花名册.csv']
./花名册/1班花名册.csv
{'姓名': '张三', '性别': '女', '学号': '00001'}
{'姓名': '李四', '性别': '女', '学号': '00002'}
./花名册/2班花名册.csv
{'姓名': 'nike', '性别': '男', '学号': '00003'}
{'姓名': 'mike', '性别': '男', '学号': '00004'}
./花名册/3班花名册.csv
{'姓名': '王五', '性别': '女', '学号': '00005'}
{'姓名': '赵六', '性别': '男', '学号': '00006'}

前2个print 是给初学者展示输出的信息,这不是必须的代码,明白的同学可以不用写。

【温馨提示】
注意with open的位置。
with open 需要的第一参数是上面for循环输出的结果,with open 读取信息也是需要3次的,因此with open 代码块也是for循环里面内容,因此with open 相对于for 循环应该有4个缩进。

【错误代码:with open 没有缩进】

import os 
import csv 

folder_path = './花名册/'
file_list = os.listdir(folder_path)
for file_name in file_list:
    file = folder_path+file_name 

with open (file,'r',encoding='utf-8') as f:
    csv_target = csv.DictReader(f)
    for row in csv_target:
        print(row)

【终端输出】

{'姓名': '王五', '性别': '女', '学号': '00005'}
{'姓名': '赵六', '性别': '男', '学号': '00006'}
./花名册/3班花名册.csv

任务4
将3个CSV文件的信息汇总到'总花名册'

import os 
import csv

# 设置表头
head= ['姓名','性别','学号']

# 设置空列表存储要写入的信息
dict_list = []

# 文件夹路径='./花名册/'
floder_path = './花名册/'

# 取花名册文件夹中的文件名列表
file_list = os.listdir(floder_path)
# 依次取出文件名
for file_name in file_list :
    # 文件路径 = 文件夹路径+文件名
    file =  floder_path  + file_name
    # print(file)

    # 每个CSV 文件读取一次,with open需要进入for 循环
    with open (file,'r',encoding='utf-8') as f :
        csv_target = csv.DictReader(f)
        # 依次取出文件信息
        # row 是一个字典,存储每一行的信息
        for row in csv_target:
            # 将字典作为元素添加到列表里
            dict_list.append(row)

# 3次循环后,3个CSV文件的信息以字典的形式全部存储在dict_list列表中
# 一次性将dict_list列表内容写入,不需要循环,没有缩进
with open ('./花名册/总花名册.csv','w',encoding='utf-8',newline='') as f :
     csv_target = csv.DictWriter(f,fieldnames=head)   
     csv_target.writeheader()
     csv_target.writerows(dict_list)
 

29_总花名册

【温馨提示】
重点关注代码中的缩进问题。

9.6.5 知识回顾

知识回顾:向空列表增加元素
append [əˈpend]:增加,增补。

# 设置一个空列表
dict_list = []

# 声明字典
dict1 = {'姓名': '张三', '成绩': '30'}
dict2 = {'姓名': '李四', '成绩': '40'}

# 往列表内新增元素:列表.apeend(要增加的元素)
dict_list.append(dict1)
dict_list.append(dict1)

# 输出列表
print(dict_list)

【终端输出】

[{'姓名': '张三', '成绩': '30'}, {'姓名': '张三', '成绩': '30'}]

知识回顾:for 循环回顾

# 新建一个列表   
list_name = ['张三','李四','王五']  

# for循环遍历列表
for name in list_name :
    print(name)

【终端输出】

张三
李四
王五

9.6.6 总结

30_csv 模块