You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取文件夹多CSV并按规则拆分输出的代码问题(非Pandas)

问题分析与代码修正

咱们来一步步拆解你代码里的问题,然后给出修复后的版本:

核心错误点

1. 判断逻辑放错位置,仅处理最后一行

你把子集的判断代码放在了for line in cr循环的外面,这意味着只有每个输入文件的最后一行会被判断是否写入子集文件,前面的所有行都被跳过了判断,这是最致命的问题。

2. 子集的筛选逻辑完全写反了

  • subset_1.csv要求存储Column1以'80B'开头的记录,但你写的条件是line[0][:3] != "80B",刚好反过来了;
  • subset_2.csv要求的是Column1不以'80B'开头 且 第4个字符不为'D',但你的条件是(line[0][:3] == "80B") and (line[0][3:4] == "D"),逻辑完全不符合需求。

3. 表头重复写入问题

你手动写入了一次表头,但注释掉了next(cr),导致每个输入文件的表头都会被写入all.csv,最终all.csv里会有多个重复的表头。另外,手动写表头不够灵活,如果输入文件的表头有变化,代码就会出错,最好直接读取输入文件的表头来复用。

修正后的代码

import glob
import csv
import os

path = r'C:\myfolder\test'
all_files = glob.glob(os.path.join(path, "*.csv"))

# 定义输出文件路径
output_paths = {
    "all": r'C:\myfolder\all.csv',
    "subset1": r'C:\myfolder\subset_1.csv',
    "subset2": r'C:\myfolder\subset_2.csv'
}

# 初始化写入器和表头标记
writers = {}
header_written = {key: False for key in output_paths}

with open(output_paths["all"], "w", newline='') as f_all, \
     open(output_paths["subset1"], "w", newline='') as f_sub1, \
     open(output_paths["subset2"], "w", newline='') as f_sub2:
    
    # 创建CSV写入器
    writers["all"] = csv.writer(f_all, delimiter=";", quoting=csv.QUOTE_MINIMAL)
    writers["subset1"] = csv.writer(f_sub1, delimiter=";", quoting=csv.QUOTE_MINIMAL)
    writers["subset2"] = csv.writer(f_sub2, delimiter=";", quoting=csv.QUOTE_MINIMAL)
    
    for filename in all_files:
        with open(filename, newline='') as infile:
            cr = csv.reader(infile, delimiter=";")
            header = next(cr)  # 读取输入文件的表头
            
            # 仅在每个输出文件第一次写入时写入表头
            for key in header_written:
                if not header_written[key]:
                    writers[key].writerow(header)
                    header_written[key] = True
            
            # 逐行处理记录
            for line in cr:
                # 写入all.csv
                writers["all"].writerow(line)
                
                # 判断subset1的条件:Column1以'80B'开头
                if line[0].startswith('80B'):
                    writers["subset1"].writerow(line)
                
                # 判断subset2的条件:Column1不以'80B'开头 且 第4个字符不是'D'
                # 注意:要确保Column1长度至少为4,避免索引越界
                if not line[0].startswith('80B') and (len(line[0]) <4 or line[0][3] != 'D'):
                    writers["subset2"].writerow(line)

修正说明

  1. 表头处理:通过next(cr)读取输入文件的表头,用header_written标记来确保每个输出文件只写入一次表头,既避免重复,又适配输入文件的表头结构;
  2. 判断逻辑位置:把子集的判断放在for line in cr循环内部,确保每一行都被检查;
  3. 修正筛选逻辑:
    • subset1使用startswith('80B')更直观准确;
    • subset2修正为符合需求的逻辑,同时增加了len(line[0]) <4的判断,避免当Column1长度不足4时出现索引越界错误;
  4. 代码结构优化:用字典管理输出路径和写入器,让代码更整洁易维护。

内容的提问来源于stack exchange,提问作者PSt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:15:51