如何匹配含无名单列的CSV与flat file数据并生成第三份文件?
方案选择
8000行的数据规模非常小,不用纠结用pandas还是原生循环:pandas适合结构化表格的聚合计算,你这个场景用Python原生文件读写加字典匹配就够了,不用装额外依赖,处理固定格式的文本行反而更灵活,性能完全够用。
实现逻辑
核心思路是先把CSV里的待匹配数字和对应序号存成哈希表(字典),匹配查找的时间复杂度是O(1),比双层循环快得多,步骤如下:
- 逐行读取CSV文件,过滤空行后,把每行的数字作为key,1~8000的自增序号作为value存入字典,读完CSV就得到所有待匹配项的映射关系
- 逐行读取flat文件,逐行处理写入新文件,不要一次性把全量文件读进内存(虽然8000行占内存极低,但逐行读写更稳,不会因为文件意外变大出问题)
- 对每行先判断是否是以
600开头的待修改行,不是的话直接原样写入新文件 - 是待修改行的话,按规则提取行内的目标数字,去之前构建的字典里查找
- 能查到匹配项的,按要求的位置把对应序号插入到行内容里,再写入新文件;查不到的话原样写入
- 对每行先判断是否是以
- 所有行处理完成后自动关闭文件句柄,不需要额外操作
参考代码
# 配置区,替换成你自己的文件路径,根据实际情况调整编码 CSV_PATH = "你的CSV文件路径.csv" FLAT_FILE_PATH = "你的待处理flat文件路径.txt" OUTPUT_PATH = "处理完成的新文件路径.txt" FILE_ENCODING = "utf-8" # 读文件乱码就换成gbk、utf-8-sig试试 # 1. 构建CSV匹配字典 match_dict = {} current_serial = 1 with open(CSV_PATH, "r", encoding=FILE_ENCODING) as f_csv: for line in f_csv: target_num = line.strip() if not target_num: continue match_dict[target_num] = current_serial current_serial += 1 # 2. 逐行处理flat文件并输出 with open(FLAT_FILE_PATH, "r", encoding=FILE_ENCODING) as f_flat, \ open(OUTPUT_PATH, "w", encoding=FILE_ENCODING) as f_out: for line in f_flat: line_content = line.rstrip("\n") # 去掉末尾换行符处理,保留原始内容格式 # 仅处理600开头的行 if line_content.startswith("600"): # --- 以下两个参数按你的实际需求修改 --- # 1. 待匹配数字的提取规则:示例是取600之后的所有内容作为待匹配数字,按实际位置改切片 match_num = line_content[3:].strip() # 2. 序号插入位置:示例是在600这个前缀之后插入序号,按实际需要的位置改切片下标 insert_pos = 3 # --- 修改分割线 --- if match_num in match_dict: serial = match_dict[match_num] new_line = f"{line_content[:insert_pos]}{serial}{line_content[insert_pos:]}\n" f_out.write(new_line) continue # 不需要修改的行直接原样写入 f_out.write(line)
需要你自行调整的细节
- 待匹配数字的提取规则:如果600开头的行里,目标数字不是从第3位开始、也不是到行尾结束,就修改代码里的切片规则,按固定长度或者分隔符提取就行
- 序号插入位置:代码里的
insert_pos是插入点的字符下标,比如要在第1个字符后面插就设成1,在整行最前面插就设成0 - 文件编码:如果打开文件出现乱码,把
FILE_ENCODING改成对应文件的编码,Windows下导出的文件常用gbk编码
这个逻辑处理8000行数据耗时在10毫秒以内,不需要做额外的性能优化,只要把提取和插入的位置调对就能出正确结果。
内容的提问来源于stack exchange,提问作者jipeto
相关产品推荐
相关产品推荐

