第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 csv

2.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文件操作。

十一、练习题

  1. 创建一个CSV文件,包含学生信息(姓名、年龄、成绩、城市),然后读取并显示。
  2. 使用DictReader读取CSV文件,并计算平均成绩。
  3. 编写一个函数,筛选出成绩大于90分的学生。
  4. 实现一个函数,将CSV文件按指定列排序。
  5. 合并多个CSV文件到一个文件中。
  6. 编写一个函数,将CSV文件转换为字典列表。
  7. 实现一个函数,将字典列表转换为CSV文件。
  8. 编写一个程序,统计CSV文件中每个城市的平均成绩。
« 上一篇 二进制文件操作 下一篇 » JSON文件操作