手动解析CSV文件并构建字典列表,核心是先读取文件原始内容,按照CSV的格式规则拆分出表头和每一行数据,再将每行数据与表头对应映射成字典,最终组成字典列表。整个过程不需要依赖任何内置或第三方模块,只需要使用基础的文件读取和字符串处理方法即可实现。

CSV格式的基本规则
要实现手动解析,首先需要明确CSV文件的通用格式规则,避免解析时出现内容错误:
- 文件第一行通常为表头,每个表头对应后续数据行的字段名称
- 默认字段之间使用英文逗号分隔
- 如果字段内容包含逗号、换行符或者双引号,整个字段会用双引号包裹
- 字段内的双引号需要使用两个连续的双引号表示转义
- 每行数据以换行符作为结束标识
手动解析的核心实现步骤
1. 读取文件原始内容
首先使用基础的文件读取方法获取CSV文件的全部内容,这里使用open函数以文本模式读取,注意指定合适的编码避免乱码:
# 读取CSV文件原始内容
def read_file_content(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()
2. 拆分表头和数据行
先按照换行符拆分所有行,第一行为表头,剩余行为数据行。这里需要注意处理可能存在的空行:
# 拆分表头和数据行
def split_header_and_rows(content):
# 按换行符拆分所有行,过滤空行
lines = [line.strip() for line in content.split('n') if line.strip()]
if not lines:
return [], []
header = lines[0]
data_rows = lines[1:]
return header, data_rows
3. 解析单个行的字段
这是手动解析最核心的部分,需要处理引号包裹、转义双引号、字段内逗号等场景,不能简单使用split(',')拆分:
# 解析单行内容,返回字段列表
def parse_line(line):
fields = []
current_field = []
in_quotes = False
i = 0
while i < len(line):
char = line[i]
if char == '"':
# 处理双引号:如果是两个连续双引号,属于转义,加入当前字段
if i + 1 < len(line) and line[i+1] == '"':
current_field.append('"')
i += 2
continue
# 否则切换引号包裹状态
in_quotes = not in_quotes
i += 1
continue
if char == ',' and not in_quotes:
# 不在引号包裹状态时遇到逗号,说明一个字段结束
fields.append(''.join(current_field))
current_field = []
i += 1
continue
# 其他情况直接加入当前字段
current_field.append(char)
i += 1
# 添加最后一个字段
fields.append(''.join(current_field))
return fields
4. 构建字典列表
将解析出的表头字段和每一行的数据字段对应,生成字典,再组成列表:
# 构建字典列表
def build_dict_list(header_line, data_rows):
# 先解析表头
headers = parse_line(header_line)
result = []
for row in data_rows:
row_fields = parse_line(row)
# 如果数据行字段数和表头不一致,按最短长度匹配
row_dict = {}
for i in range(min(len(headers), len(row_fields))):
row_dict[headers[i]] = row_fields[i]
result.append(row_dict)
return result
5. 完整调用示例
将上述步骤组合起来,实现完整的解析流程:
# 完整解析函数
def manual_parse_csv(file_path):
content = read_file_content(file_path)
header_line, data_rows = split_header_and_rows(content)
if not header_line:
return []
return build_dict_list(header_line, data_rows)
# 使用示例,假设当前目录下有test.csv文件
if __name__ == '__main__':
csv_data = manual_parse_csv('test.csv')
for item in csv_data:
print(item)
边界场景处理说明
上述实现已经覆盖了大部分常见场景,若需要适配更多特殊情况,可以补充以下处理逻辑:
- 如果CSV文件使用其他分隔符(如制表符),只需将
parse_line函数中的逗号判断替换为对应分隔符即可 - 如果表头存在重复字段,可以在解析表头时给重复字段添加后缀区分
- 如果数据行存在缺失字段,可以在构建字典时给缺失的表头字段赋值空字符串
解析结果验证
假设test.csv文件内容如下:
name,age,city 张三,25,北京 李四,30,"上海,浦东" 王五,28,广州
运行上述完整解析代码后,输出的字典列表为:
[
{'name': '张三', 'age': '25', 'city': '北京'},
{'name': '李四', 'age': '30', 'city': '上海,浦东'},
{'name': '王五', 'age': '28', 'city': '广州'}
]
可以看到包含逗号的字段内容被正确解析,没有因为字段内的逗号被错误拆分,说明手动解析逻辑符合CSV格式规则。