如何使用Python动态拼接两个CSV文件?代码无报错但输出异常求解
问题根源
你遇到的输出异常主要是以下4个代码逻辑错误导致的:
- 读写同一个文件的操作逻辑错误:使用
r+模式同时读写同一个CSV时,读操作和写操作共用文件指针,边读边写会导致指针位置错乱,出现内容覆盖不全、行乱序、意外插入空行的问题。 refcds函数逻辑完全错误:- 函数内遍历参考文件第一行之后就直接
return,根本不会遍历后续的参考区间行,只会校验第一个参考区间是否匹配 - 多余的
for i in range(0,12)循环无实际作用 - 直接用字符串格式的数值比较大小,会出现
"100" < "99"的错误判断结果 - 没有处理参考文件中的空行,遇到空行取
rows[3]会触发索引报错
- 函数内遍历参考文件第一行之后就直接
- 未处理CSV换行符问题:打开CSV文件时未加
newline=''参数,容易生成多余空行 - 效率问题:每次调用
refcds都会重新打开读取一次参考文件,文件IO开销极大
修正方案
推荐先把所有数据读到内存处理完成后,再一次性写入文件,同时提前把参考文件的有效CDS区间加载到内存复用,修正后的代码如下:
import csv # 提前加载参考文件中的有效CDS区间,只需要读取一次 def load_cds_intervals(): cds_intervals = [] with open("chrM_genes.csv", "r", newline='') as infile: r = csv.reader(infile) for row in r: # 跳过空行、非CDS行、字段不足的行 if not row or len(row) <5 or row[0] != "CDS": continue try: start = int(row[3]) end = int(row[4]) cds_intervals.append((start, end)) except ValueError: # 跳过数值格式异常的行 continue return cds_intervals cds_list = load_cds_intervals() # 处理目标文件 processed_rows = [] with open('chrM_location.csv','r', newline='') as f: reader = csv.reader(f) for row in reader: # 读到END行终止 if len(row)>=2 and row[1] == 'END': break # 表头直接保留 if len(row)>=2 and row[1] == 'POS': # 可以给表头加新增列的列名,这里按需修改 row.extend(["type","cds_start","cds_end","pos_offset"]) processed_rows.append(row) continue # 处理数据行 try: pos = int(row[1]) except (ValueError, IndexError): # 格式异常的行直接保留原内容 processed_rows.append(row) continue # 匹配CDS区间 match = None for start, end in cds_list: if start <= pos <= end: match = ["CDS", str(start), str(end), str(pos - start + 1)] break if match: row.extend(match) processed_rows.append(row) # 处理完成后写回原文件 with open('chrM_location.csv','w', newline='') as f: writer = csv.writer(f) writer.writerows(processed_rows)
补充说明
如果不需要保留未匹配区间的行,只需要在匹配判断的地方,匹配成功才把行加入processed_rows列表即可。
内容的提问来源于stack exchange,提问作者Joy Zheng
相关产品推荐
相关产品推荐

