Python 一维数据、二维数据及 CSV 文件操作全解析(附实例)
在数据处理中,一维数据和二维数据是最基础的数据结构。CSV(逗号分隔值)作为一种轻量级文件格式,是存储和交换这两类数据的常用载体。本文将系统讲解一维数据、二维数据的概念、表示方法,以及如何通过 Python 对 CSV 文件进行读写操作,结合20+ 实例覆盖基础到进阶场景。
一、一维数据:线性结构的数据集合
1.1 概念与特征
- 定义:由相同类型的数据元素组成的线性序列(仅有一个维度),如:名单、数值列表、标签集合等。
- 特征:数据元素之间是平等的线性关系,无层级或嵌套。
1.2 Python 中一维数据的表示
Python 中最常用 列表(list) 表示一维数据,也可用元组(tuple)(不可变)或集合(set)(去重)。
示例 1:一维数据的表示形式
# 1. 列表(最常用,可修改)
names = ["张三", "李四", "王五", "赵六"] # 字符串型一维数据
scores = [90, 85, 95, 88] # 数值型一维数据# 2. 元组(不可修改,适合固定数据)
weekdays = ("周一", "周二", "周三", "周四", "周五")# 3. 集合(自动去重,无序)
tags = {"Python", "数据处理", "CSV", "Python"} # 去重后为 {"Python", "数据处理", "CSV"}print("列表形式:", names)
print("元组形式:", weekdays)
print("集合形式:", tags)
1.3 一维数据的基本操作
包括遍历、索引访问、切片、排序等,核心是列表的基础操作。
示例 2:一维数据的常用操作
scores = [90, 85, 95, 88, 76]# 1. 遍历
print("所有分数:", end=" ")
for score in scores:print(score, end=" ") # 输出:90 85 95 88 76# 2. 索引访问(获取/修改元素)
print("\n\n第二个分数(索引1):", scores[1]) # 输出:85
scores[4] = 80 # 修改第五个元素
print("修改后第五个分数:", scores[4]) # 输出:80# 3. 切片(获取子序列)
print("\n前3个分数:", scores[:3]) # 输出:[90, 85, 95]
print("后2个分数:", scores[-2:]) # 输出:[88, 80]# 4. 排序
sorted_scores = sorted(scores) # 升序排序(不修改原列表)
print("\n升序排序:", sorted_scores) # 输出:[80, 85, 88, 90, 95]
scores.sort(reverse=True) # 原列表降序排序
print("降序排序(原列表):", scores) # 输出:[95, 90, 88, 85, 80]
二、二维数据:表格结构的数据集合
2.1 概念与特征
- 定义:由多个一维数据按行排列组成的表格型数据(有行和列两个维度),如:学生信息表、成绩表、CSV 表格等。
- 特征:每个元素由「行索引」和「列索引」共同定位,行内元素类型可不同(如一行包含姓名、年龄、成绩)。
2.2 Python 中二维数据的表示
Python 中最常用 列表的列表(list of lists) 表示二维数据,外层列表代表行,内层列表代表每行的列元素。
示例 3:二维数据的表示形式
# 学生信息表:每行包含 [姓名, 年龄, 性别, 成绩]
students = [["张三", 20, "男", 90],["李四", 21, "女", 85],["王五", 19, "男", 95],["赵六", 22, "女", 88]
]# 打印二维数据(模拟表格)
print("学生信息表:")
for row in students:print(row)# 输出:
# 学生信息表:
# ['张三', 20, '男', 90]
# ['李四', 21, '女', 85]
# ['王五', 19, '男', 95]
# ['赵六', 22, '女', 88]
2.3 二维数据的基本操作
包括访问元素、遍历、增删行/列、按条件筛选等。
示例 4:二维数据的常用操作
students = [["张三", 20, "男", 90],["李四", 21, "女", 85],["王五", 19, "男", 95],["赵六", 22, "女", 88]
]# 1. 访问元素(行索引, 列索引)
print("第2行第1列(姓名):", students[1][0]) # 输出:李四
print("第3行第4列(成绩):", students[2][3]) # 输出:95# 2. 遍历所有元素(行优先)
print("\n所有学生信息(行+列):")
for i, row in enumerate(students): # i 是行索引for j, value in enumerate(row): # j 是列索引print(f"({i},{j}): {value}", end=" | ")print() # 换行# 3. 增加一行( append() )
new_student = ["孙七", 20, "男", 82]
students.append(new_student)
print("\n增加一行后:", students[-1]) # 输出新增行# 4. 按条件筛选(如成绩 >=90 的学生)
excellent = [row for row in students if row[3] >= 90]
print("\n成绩优秀的学生:", excellent) # 输出:[['张三', 20, '男', 90], ['王五', 19, '男', 95]]# 5. 提取一列(如所有学生的成绩)
scores = [row[3] for row in students]
print("\n所有学生成绩:", scores) # 输出:[90, 85, 95, 88, 82]# 6. 排序(按年龄升序)
students.sort(key=lambda x: x[1]) # 按第2列(年龄)排序
print("\n按年龄排序后:")
for row in students:print(row)
三、CSV 文件:一维/二维数据的存储格式
CSV(Comma-Separated Values,逗号分隔值)是一种纯文本格式,用逗号分隔字段,换行分隔记录,广泛用于数据交换。
3.1 CSV 格式规则
- 每行代表一条记录(一维数据的一个元素或二维数据的一行);
- 字段间用逗号
,分隔(也可用制表符\t等,称为 TSV); - 若字段包含逗号、换行符等特殊字符,需用双引号
""包裹; - 首行可作为表头(二维数据的列名)。
示例 5:标准 CSV 格式示例(students.csv)
姓名,年龄,性别,成绩
张三,20,男,90
李四,21,女,85
王五,19,男,95
赵六,22,女,88
示例 6:含特殊字符的 CSV 格式(special.csv)
名称,描述
苹果,"红,甜,脆" # 字段含逗号,用双引号包裹
香蕉,"黄色
软质水果" # 字段含换行符,用双引号包裹
四、Python 操作 CSV 文件:内置 csv 模块
Python 标准库 csv 提供了专门处理 CSV 文件的工具,支持读写一维/二维数据,自动处理特殊字符。
4.1 写入 CSV 文件(一维数据)
一维数据写入 CSV 时,通常每行一个元素(或作为一行的多个字段)。
示例 7:将一维列表写入 CSV(每行一个元素)
import csv# 一维数据(名单)
names = ["张三", "李四", "王五", "赵六"]# 写入 CSV(每行一个名字)
with open("names.csv", "w", encoding="utf-8", newline="") as f: # newline="" 避免空行writer = csv.writer(f) # 创建写入器for name in names:writer.writerow([name]) # writerow() 接收可迭代对象,单个元素需用列表包裹print("一维数据写入完成,文件内容:")
with open("names.csv", "r", encoding="utf-8") as f:print(f.read())
输出结果(names.csv 内容):
张三
李四
王五
赵六
示例 8:将一维数据作为一行字段写入 CSV
import csv# 一维数据(一条学生信息)
student = ["孙七", 20, "男", 82]# 写入 CSV(一行包含所有字段)
with open("single_student.csv", "w", encoding="utf-8", newline="") as f:writer = csv.writer(f)writer.writerow(student) # 直接写入列表(一行多个字段)print("单行多字段写入完成,文件内容:")
with open("single_student.csv", "r", encoding="utf-8") as f:print(f.read())
输出结果(single_student.csv 内容):
孙七,20,男,82
4.2 写入 CSV 文件(二维数据)
二维数据(列表的列表)可直接用 writerows() 批量写入,或用 writerow() 逐行写入。
示例 9:写入带表头的二维数据(学生表)
import csv# 二维数据(含表头)
students = [["姓名", "年龄", "性别", "成绩"], # 表头["张三", 20, "男", 90],["李四", 21, "女", 85],["王五", 19, "男", 95],["赵六", 22, "女", 88]
]# 批量写入二维数据
with open("students.csv", "w", encoding="utf-8", newline="") as f:writer = csv.writer(f)writer.writerows(students) # writerows() 接收二维列表print("二维数据写入完成,文件内容:")
with open("students.csv", "r", encoding="utf-8") as f:print(f.read())
输出结果(students.csv 内容):
姓名,年龄,性别,成绩
张三,20,男,90
李四,21,女,85
王五,19,男,95
赵六,22,女,88
示例 10:用字典写入 CSV(更直观的表头映射)
csv.DictWriter 可通过字典键值对写入,键对应表头,值对应字段,适合字段较多的场景。
import csv# 表头
headers = ["姓名", "年龄", "性别", "成绩"]# 二维数据(字典列表)
students_dict = [{"姓名": "张三", "年龄": 20, "性别": "男", "成绩": 90},{"姓名": "李四", "年龄": 21, "性别": "女", "成绩": 85},{"姓名": "王五", "年龄": 19, "性别": "男", "成绩": 95}
]with open("students_dict.csv", "w", encoding="utf-8", newline="") as f:# 初始化 DictWriter,指定表头writer = csv.DictWriter(f, fieldnames=headers)writer.writeheader() # 写入表头writer.writerows(students_dict) # 写入数据行print("字典格式二维数据写入完成,文件内容:")
with open("students_dict.csv", "r", encoding="utf-8") as f:print(f.read())
输出结果(students_dict.csv 内容):
姓名,年龄,性别,成绩
张三,20,男,90
李四,21,女,85
王五,19,男,95
4.3 读取 CSV 文件(一维数据)
读取一维数据时,根据 CSV 格式选择按行读取单个元素或一行多个字段。
示例 11:读取每行一个元素的 CSV(names.csv)
import csv# 读取一维数据(每行一个名字)
with open("names.csv", "r", encoding="utf-8") as f:reader = csv.reader(f) # 创建读取器names = [row[0] for row in reader] # 每行第一个元素(唯一元素)print("读取的一维数据(名单):", names) # 输出:['张三', '李四', '王五', '赵六']
示例 12:读取一行多字段的 CSV 作为一维数据
import csv# 读取单行多字段的 CSV(single_student.csv)
with open("single_student.csv", "r", encoding="utf-8") as f:reader = csv.reader(f)student = next(reader) # 读取第一行(仅一行)print("读取的一维数据(学生信息):", student) # 输出:['孙七', '20', '男', '82']
# 注意:CSV 读取的数值默认是字符串,需手动转换
student[1] = int(student[1]) # 年龄转为整数
student[3] = int(student[3]) # 成绩转为整数
print("转换后:", student) # 输出:['孙七', 20, '男', 82]
4.4 读取 CSV 文件(二维数据)
读取二维数据时,可用 csv.reader 或 csv.DictReader(按字典读取,更易按表头访问)。
示例 13:用 csv.reader 读取带表头的二维数据
import csvwith open("students.csv", "r", encoding="utf-8") as f:reader = csv.reader(f)headers = next(reader) # 读取表头(第一行)students = [row for row in reader] # 读取数据行print("表头:", headers) # 输出:['姓名', '年龄', '性别', '成绩']
print("数据行:", students) # 输出二维列表
# 转换数值类型(年龄和成绩)
for row in students:row[1] = int(row[1])row[3] = int(row[3])
print("转换后数据:", students)
输出结果:
表头: ['姓名', '年龄', '性别', '成绩']
数据行: [['张三', '20', '男', '90'], ['李四', '21', '女', '85'], ['王五', '19', '男', '95'], ['赵六', '22', '女', '88']]
转换后数据: [['张三', 20, '男', 90], ['李四', 21, '女', 85], ['王五', 19, '男', 95], ['赵六', 22, '女', 88]]
示例 14:用 csv.DictReader 读取(按表头访问更直观)
import csvwith open("students.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f) # 自动将第一行作为表头students_dict = [row for row in reader] # 每行是一个字典print("字典格式数据:")
for row in students_dict:print(row)# 按表头访问字段(注意:值是字符串,需转换)
print("\n所有学生姓名和成绩:")
for row in students_dict:print(f"{row['姓名']}:{int(row['成绩'])}分")
输出结果:
字典格式数据:
{'姓名': '张三', '年龄': '20', '性别': '男', '成绩': '90'}
{'姓名': '李四', '年龄': '21', '性别': '女', '成绩': '85'}
{'姓名': '王五', '年龄': '19', '性别': '男', '成绩': '95'}
{'姓名': '赵六', '年龄': '22', '性别': '女', '成绩': '88'}所有学生姓名和成绩:
张三:90分
李四:85分
王五:95分
赵六:88分
4.5 处理特殊字符的 CSV 文件
csv 模块会自动处理含逗号、换行符等特殊字符的字段(需用双引号包裹)。
示例 15:读取含特殊字符的 CSV(special.csv)
import csvwith open("special.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f)data = list(reader)print("含特殊字符的数据:")
for row in data:print(f"名称:{row['名称']},描述:{row['描述']}")
输出结果:
含特殊字符的数据:
名称:苹果,描述:红,甜,脆
名称:香蕉,描述:黄色
软质水果
五、进阶场景:CSV 数据处理实战
场景 1:筛选并导出符合条件的数据
需求:从学生表中筛选出成绩 ≥90 分的学生,导出为新的 CSV 文件。
import csv# 读取原始数据
with open("students.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f)students = list(reader)# 筛选成绩 ≥90 的学生
excellent = [row for row in students if int(row["成绩"]) >= 90]# 导出到新文件
with open("excellent_students.csv", "w", encoding="utf-8", newline="") as f:if excellent: # 确保有数据writer = csv.DictWriter(f, fieldnames=excellent[0].keys())writer.writeheader()writer.writerows(excellent)print("筛选完成,优秀学生数据:", excellent)
输出结果(excellent_students.csv 内容):
姓名,年龄,性别,成绩
张三,20,男,90
王五,19,男,95
场景 2:计算二维数据的统计信息
需求:计算学生表中的平均年龄、平均成绩、最高成绩。
import csvwith open("students.csv", "r", encoding="utf-8") as f:reader = csv.DictReader(f)students = list(reader)# 提取数值列(转换为整数)
ages = [int(row["年龄"]) for row in students]
scores = [int(row["成绩"]) for row in students]# 计算统计量
avg_age = sum(ages) / len(ages)
avg_score = sum(scores) / len(scores)
max_score = max(scores)print(f"平均年龄:{avg_age:.1f}岁") # 输出:平均年龄:20.5岁
print(f"平均成绩:{avg_score:.1f}分") # 输出:平均成绩:89.5分
print(f"最高成绩:{max_score}分") # 输出:最高成绩:95分
场景 3:CSV 与 Excel 格式互转(需第三方库)
pandas 库可简化 CSV 与 Excel 的互转(需安装:pip install pandas openpyxl)。
import pandas as pd# 1. CSV 转 Excel
df = pd.read_csv("students.csv", encoding="utf-8") # 读取 CSV
df.to_excel("students.xlsx", index=False) # 导出为 Excel(index=False 不保留行索引)# 2. Excel 转 CSV
df = pd.read_excel("students.xlsx") # 读取 Excel
df.to_csv("students_from_excel.csv", index=False, encoding="utf-8") # 导出为 CSVprint("格式转换完成")
六、常见问题与避坑指南
-
中文乱码问题
- 读写时显式指定
encoding="utf-8"(推荐),若文件是 GBK 编码,需用encoding="gbk"; - 避免用记事本直接编辑 CSV(可能默认 ANSI 编码),推荐用 VS Code、Excel 等工具。
- 读写时显式指定
-
空行问题
- 写入 CSV 时,
open()函数需指定newline="",否则 Windows 系统会自动添加空行。
- 写入 CSV 时,
-
数据类型转换
- CSV 读取的所有字段默认是字符串(
str),数值型数据需手动转换为int或float。
- CSV 读取的所有字段默认是字符串(
-
特殊分隔符
- 若 CSV 用制表符(
\t)分隔(TSV),可指定delimiter="\t":reader = csv.reader(f, delimiter="\t") # 读取 TSV 文件
- 若 CSV 用制表符(
-
大文件处理
- 处理 GB 级 CSV 时,避免用
list(reader)一次性加载,应逐行迭代:with open("large.csv", "r") as f:reader = csv.reader(f)for row in reader: # 逐行处理,节省内存process(row)
- 处理 GB 级 CSV 时,避免用
七、总结
- 一维数据:线性结构,用列表表示,适合存储序列型数据(如名单、数值列表);
- 二维数据:表格结构,用列表的列表表示,适合存储带行和列的结构化数据(如学生表);
- CSV 操作:
- 写入:用
csv.writer(列表)或csv.DictWriter(字典),注意newline=""和编码; - 读取:用
csv.reader(返回列表)或csv.DictReader(返回字典,按表头访问); - 特殊处理:
csv模块自动处理含逗号、换行符的字段,数值需手动转换类型。
- 写入:用
掌握这些内容后,可轻松应对数据导入导出、格式转换、简单数据分析等常见任务,为更复杂的数据处理(如用 pandas 分析)打下基础。