Python校验CSV学生数据:无法正确输出违规字段问题求助
学生信息CSV校验问题解决方案
核心修改方向
将整行有效性判断拆解为字段级独立校验,为每个字段编写针对性校验逻辑,收集具体错误信息,而非仅标记整行无效。
示例修改代码(Python)
import csv from datetime import datetime # 学号校验:7位数字,首字符为0,第二位为8/9 def check_student_id(sid): errors = [] if len(sid) != 7: errors.append("需为7位") if not sid.isdigit(): errors.append("仅含数字") if len(sid) >= 2 and (sid[0] != '0' or sid[1] not in ('8', '9')): errors.append("首字符为0且第二位是8/9") return errors # 姓名校验:仅含字母 def check_name(name): errors = [] if not name.isalpha(): errors.append("仅允许字母") return errors # 出生日期校验:YYYY-MM-DD格式,年份范围1960-2004 def check_birthdate(birth_str): errors = [] try: birth_date = datetime.strptime(birth_str, '%Y-%m-%d') if not (1960 <= birth_date.year <= 2004): errors.append(f"年份需在1960-2004之间(当前为{birth_date.year})") except ValueError: errors.append("格式需为YYYY-MM-DD") return errors # 专业校验:仅限INF、TINF、CMD、AI def check_major(major): allowed = {'INF', 'TINF', 'CMD', 'AI'} errors = [] if major not in allowed: errors.append(f"需为{', '.join(allowed)}之一") return errors # 处理CSV主函数 def process_csv(file_path): valid_records = [] invalid_records = [] with open(file_path, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for line_num, row in enumerate(reader, start=2): # 行号从2开始(跳过表头) field_errors = [] # 逐一校验字段并收集错误 id_err = check_student_id(row['学号']) if id_err: field_errors.append(f"学号:{'; '.join(id_err)}") name_err = check_name(row['姓名']) if name_err: field_errors.append(f"姓名:{'; '.join(name_err)}") birth_err = check_birthdate(row['出生日期']) if birth_err: field_errors.append(f"出生日期:{'; '.join(birth_err)}") major_err = check_major(row['专业']) if major_err: field_errors.append(f"专业:{'; '.join(major_err)}") # 分类存储有效/无效记录 if not field_errors: valid_records.append(row) else: invalid_records.append({ '行号': line_num, '错误详情': '; '.join(field_errors), '原始数据': row }) # 输出结果 print("=== 有效记录 ===") for item in valid_records: print(item) print("\n=== 无效记录(含错误详情) ===") for item in invalid_records: print(f"行号:{item['行号']} | 错误:{item['错误详情']}") print(f"原始数据:{item['原始数据']}\n") # 调用示例 process_csv('students.csv')
代码说明
- 每个字段对应独立校验函数,返回该字段的所有错误描述,而非仅布尔值
- 遍历CSV时,对每行的四个字段逐一校验,汇总所有错误信息
- 无效行记录行号、错误详情、原始数据,便于精准定位问题
- 输出时明确区分有效记录和带具体错误的无效记录
测试示例
假设你的CSV片段如下:
学号,姓名,出生日期,专业
0812345,Alice,1999-05-20,INF
0712345,Bob,2005-03-10,ENG
09abc12,Charlie,1980/10/05,AI
081234,Dave,1975-07-15,CMD
运行代码后会输出:
- 第一行列为有效记录
- 第二行错误:学号:首字符为0且第二位是8/9;出生日期:年份需在1960-2004之间(当前为2005);专业:需为INF, TINF, CMD, AI之一
- 第三行错误:学号:仅含数字;出生日期:格式需为YYYY-MM-DD
- 第四行错误:学号:需为7位
内容的提问来源于stack exchange,提问作者jb18
相关产品推荐
相关产品推荐

