第84集:CSV文件操作
学习目标
- 理解CSV文件的基本概念和格式
- 掌握csv模块的基本使用方法
- 学会读取和写入CSV文件
- 掌握CSV文件的高级操作
- 学会处理CSV文件中的常见问题
一、CSV文件概述
1.1 什么是CSV文件
CSV(Comma-Separated Values,逗号分隔值)是一种常见的文本文件格式,用于存储表格数据。每行代表一条记录,字段之间用逗号分隔。
1.2 CSV文件格式示例
姓名,年龄,城市
张三,25,北京
李四,30,上海
王五,28,广州1.3 CSV文件的特点
- 简单易读,可以用文本编辑器打开
- 支持多种数据类型(文本、数字、日期等)
- 可以被Excel等电子表格软件直接打开
- 适合存储结构化数据
二、csv模块简介
2.1 导入csv模块
import csv2.2 csv模块的主要组件
- reader:读取CSV文件
- writer:写入CSV文件
- DictReader:以字典形式读取CSV文件
- DictWriter:以字典形式写入CSV文件
三、读取CSV文件
3.1 使用reader读取CSV文件
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)注意: 打开CSV文件时,建议使用newline=''参数,以避免在不同操作系统上出现换行符问题。
3.2 读取包含标题行的CSV文件
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
header = next(reader) # 读取标题行
print("标题行:", header)
for row in reader:
print(row)3.3 使用DictReader读取CSV文件
DictReader会将每一行转换为一个字典,键为标题行的字段名。
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
for row in reader:
print(row)
print(f"姓名:{row['姓名']}, 年龄:{row['age']}")四、写入CSV文件
4.1 使用writer写入CSV文件
import csv
data = [
['张三', 25, '北京'],
['李四', 30, '上海'],
['王五', 28, '广州']
]
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerow(['姓名', '年龄', '城市']) # 写入标题行
writer.writerows(data) # 写入多行数据4.2 使用DictWriter写入CSV文件
import csv
data = [
{'姓名': '张三', '年龄': 25, '城市': '北京'},
{'姓名': '李四', '年龄': 30, '城市': '上海'},
{'姓名': '王五', '年龄': 28, '城市': '广州'}
]
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
fieldnames = ['姓名', '年龄', '城市']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # 写入标题行
writer.writerows(data) # 写入多行数据五、CSV文件的高级操作
5.1 指定分隔符
默认情况下,CSV文件使用逗号作为分隔符。可以使用delimiter参数指定其他分隔符。
import csv
# 读取使用分号分隔的CSV文件
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f, delimiter=';')
for row in reader:
print(row)
# 写入使用分号分隔的CSV文件
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f, delimiter=';')
writer.writerow(['姓名', '年龄', '城市'])
writer.writerow(['张三', 25, '北京'])5.2 处理包含特殊字符的字段
如果字段中包含分隔符、换行符或引号,需要使用引号包裹。
import csv
data = [
['张三', '25', '北京,中国'],
['李四', '30', '上海\n中国'],
['王五', '28', '广州"中国']
]
with open('special.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerow(['姓名', '年龄', '地址'])
writer.writerows(data)5.3 指定引号字符
可以使用quotechar参数指定引号字符。
import csv
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f, quotechar="'")
writer.writerow(['姓名', '年龄', '城市'])
writer.writerow(['张三', 25, '北京'])5.4 处理空值
可以使用quoting参数控制何时使用引号。
import csv
# QUOTE_MINIMAL:仅在必要时使用引号(默认)
# QUOTE_ALL:所有字段都使用引号
# QUOTE_NONNUMERIC:非数字字段使用引号
# QUOTE_NONE:不使用引号
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f, quoting=csv.QUOTE_ALL)
writer.writerow(['姓名', '年龄', '城市'])
writer.writerow(['张三', 25, '北京'])六、CSV文件数据处理
6.1 统计CSV文件数据
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
total_age = 0
count = 0
for row in reader:
total_age += int(row['年龄'])
count += 1
average_age = total_age / count
print(f"平均年龄:{average_age:.2f}")6.2 筛选CSV文件数据
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
# 筛选年龄大于25的记录
filtered_data = [row for row in reader if int(row['年龄']) > 25]
for row in filtered_data:
print(row)6.3 排序CSV文件数据
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
data = list(reader)
# 按年龄排序
sorted_data = sorted(data, key=lambda x: int(x['年龄']))
for row in sorted_data:
print(row)6.4 合并多个CSV文件
import csv
def merge_csv_files(output_file, input_files):
with open(output_file, 'w', encoding='utf-8', newline='') as out_f:
writer = None
for input_file in input_files:
with open(input_file, 'r', encoding='utf-8', newline='') as in_f:
reader = csv.DictReader(in_f)
if writer is None:
writer = csv.DictWriter(out_f, fieldnames=reader.fieldnames)
writer.writeheader()
writer.writerows(reader)
merge_csv_files('merged.csv', ['file1.csv', 'file2.csv', 'file3.csv'])七、CSV文件与数据结构转换
7.1 CSV转换为列表
import csv
def csv_to_list(file_path):
with open(file_path, 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
return list(reader)
data = csv_to_list('data.csv')
print(data)7.2 CSV转换为字典列表
import csv
def csv_to_dict_list(file_path):
with open(file_path, 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
return list(reader)
data = csv_to_dict_list('data.csv')
print(data)7.3 列表转换为CSV
import csv
def list_to_csv(data, file_path):
with open(file_path, 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerows(data)
data = [
['姓名', '年龄', '城市'],
['张三', 25, '北京'],
['李四', 30, '上海']
]
list_to_csv(data, 'output.csv')7.4 字典列表转换为CSV
import csv
def dict_list_to_csv(data, file_path):
if not data:
return
fieldnames = data[0].keys()
with open(file_path, 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
data = [
{'姓名': '张三', '年龄': 25, '城市': '北京'},
{'姓名': '李四', '年龄': 30, '城市': '上海'}
]
dict_list_to_csv(data, 'output.csv')八、CSV文件常见问题
8.1 编码问题
# 指定正确的编码
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)8.2 换行符问题
使用newline=''参数可以避免换行符问题。
# 推荐
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 不推荐
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)8.3 空行处理
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
# 跳过空行
if not row:
continue
print(row)8.4 数据类型转换
import csv
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
for row in reader:
# 转换数据类型
row['年龄'] = int(row['年龄'])
row['成绩'] = float(row['成绩'])
print(row)九、最佳实践
9.1 使用with语句
# 推荐
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 不推荐
f = open('data.csv', 'r', encoding='utf-8', newline='')
reader = csv.reader(f)
for row in reader:
print(row)
f.close()9.2 使用DictReader和DictWriter
# 推荐:使用DictReader
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['姓名'])
# 不推荐:使用普通reader
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
print(row[0]) # 需要记住列索引9.3 指定newline参数
# 推荐
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 不推荐
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)9.4 异常处理
import csv
try:
with open('data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
for row in reader:
print(row)
except FileNotFoundError:
print('文件不存在')
except UnicodeDecodeError:
print('编码错误')
except Exception as e:
print(f'发生错误:{e}')十、总结
本集学习了CSV文件操作的知识:
- CSV文件的基本概念和格式
- csv模块的使用方法
- 读取和写入CSV文件
- CSV文件的高级操作
- CSV文件的数据处理和转换
- CSV文件常见问题和最佳实践
CSV文件是一种简单而强大的数据交换格式,广泛应用于数据存储和交换。下一集我们将学习JSON文件操作。
十一、练习题
- 创建一个CSV文件,包含学生信息(姓名、年龄、成绩、城市),然后读取并显示。
- 使用DictReader读取CSV文件,并计算平均成绩。
- 编写一个函数,筛选出成绩大于90分的学生。
- 实现一个函数,将CSV文件按指定列排序。
- 合并多个CSV文件到一个文件中。
- 编写一个函数,将CSV文件转换为字典列表。
- 实现一个函数,将字典列表转换为CSV文件。
- 编写一个程序,统计CSV文件中每个城市的平均成绩。